|
@@ -0,0 +1,137 @@
|
|
|
|
|
+# ===================================================================
|
|
|
|
|
+# extraer_combos_sap.py
|
|
|
|
|
+# Función standalone para extraer combinaciones de SAP2000 con formato 100% idéntico al reporte oficial
|
|
|
|
|
+# ===================================================================
|
|
|
|
|
+
|
|
|
|
|
+import os
|
|
|
|
|
+import tkinter as tk
|
|
|
|
|
+from tkinter.filedialog import asksaveasfilename
|
|
|
|
|
+from openpyxl import Workbook
|
|
|
|
|
+from openpyxl.styles import Font, PatternFill, Alignment
|
|
|
|
|
+from openpyxl.utils import get_column_letter
|
|
|
|
|
+
|
|
|
|
|
+# Colores exactos de SAP2000
|
|
|
|
|
+AZUL_SAP = "000080" # Azul marino cabecera
|
|
|
|
|
+AMARILLO_SAP = "FFFF00" # Amarillo fila de tipos
|
|
|
|
|
+
|
|
|
|
|
+# Barra de progreso (la misma que usas en el script principal)
|
|
|
|
|
+def printProgressBar(iteration, total, prefix='', suffix='', decimals=1, length=50, fill='█'):
|
|
|
|
|
+ percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
|
|
|
|
|
+ filledLength = int(length * iteration // total)
|
|
|
|
|
+ bar = fill * filledLength + '-' * (length - filledLength)
|
|
|
|
|
+ print(f'\r{prefix} |{bar}| {percent}% {suffix}', end="")
|
|
|
|
|
+ if iteration == total:
|
|
|
|
|
+ print()
|
|
|
|
|
+
|
|
|
|
|
+def extraer_combinaciones_a_excel(SapModel, ruta_excel_origen=None):
|
|
|
|
|
+ """
|
|
|
|
|
+ Extrae todas las combinaciones de SAP2000 y las guarda en Excel
|
|
|
|
|
+ con el formato EXACTO del reporte oficial de SAP2000.
|
|
|
|
|
+
|
|
|
|
|
+ Parámetros:
|
|
|
|
|
+ SapModel: objeto SAP2000 ya conectado
|
|
|
|
|
+ ruta_excel_origen: (opcional) ruta del Excel original para sugerir nombre y carpeta
|
|
|
|
|
+ """
|
|
|
|
|
+ # --- Ventana para guardar ---
|
|
|
|
|
+ root = tk.Tk()
|
|
|
|
|
+ root.withdraw()
|
|
|
|
|
+ root.attributes('-topmost', True)
|
|
|
|
|
+
|
|
|
|
|
+ # Sugerir nombre y carpeta inteligente
|
|
|
|
|
+ if ruta_excel_origen and os.path.exists(ruta_excel_origen):
|
|
|
|
|
+ carpeta = os.path.dirname(ruta_excel_origen)
|
|
|
|
|
+ nombre_base = os.path.splitext(os.path.basename(ruta_excel_origen))[0]
|
|
|
|
|
+ nombre_sugerido = f"{nombre_base}_COMBINACIONES_SAP2000.xlsx"
|
|
|
|
|
+ initialfile = os.path.join(carpeta, nombre_sugerido)
|
|
|
|
|
+ else:
|
|
|
|
|
+ initialfile = "COMBINACIONES_SAP2000.xlsx"
|
|
|
|
|
+
|
|
|
|
|
+ archivo_salida = asksaveasfilename(
|
|
|
|
|
+ initialfile=initialfile,
|
|
|
|
|
+ defaultextension=".xlsx",
|
|
|
|
|
+ filetypes=[("Excel files", "*.xlsx")],
|
|
|
|
|
+ title="Guardar combinaciones (formato SAP2000)"
|
|
|
|
|
+ )
|
|
|
|
|
+ root.destroy()
|
|
|
|
|
+
|
|
|
|
|
+ if not archivo_salida:
|
|
|
|
|
+ print("\nExportación cancelada por el usuario.")
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ # --- Extraer combinaciones ---
|
|
|
|
|
+ ret = SapModel.RespCombo.GetNameList()
|
|
|
|
|
+ num_combos = ret[0]
|
|
|
|
|
+ combo_names = ret[1]
|
|
|
|
|
+
|
|
|
|
|
+ datos = []
|
|
|
|
|
+ print(f"\nExtrayendo {num_combos} combinaciones con formato oficial SAP2000...")
|
|
|
|
|
+
|
|
|
|
|
+ for i, combo_name in enumerate(combo_names):
|
|
|
|
|
+ tipo = SapModel.RespCombo.GetTypeOAPI(combo_name)[0]
|
|
|
|
|
+ tipo_texto = "Linear Add" if tipo == 0 else "Envelope" if tipo == 1 else "Other"
|
|
|
|
|
+
|
|
|
|
|
+ casos = SapModel.RespCombo.GetCaseList(combo_name)
|
|
|
|
|
+ nombres_casos = casos[2]
|
|
|
|
|
+ factores = casos[3]
|
|
|
|
|
+
|
|
|
|
|
+ if len(nombres_casos) == 0:
|
|
|
|
|
+ datos.append([combo_name, tipo_texto, "", ""])
|
|
|
|
|
+ else:
|
|
|
|
|
+ for j, caso in enumerate(nombres_casos):
|
|
|
|
|
+ if j == 0:
|
|
|
|
|
+ datos.append([combo_name, tipo_texto, caso, factores[j]])
|
|
|
|
|
+ else:
|
|
|
|
|
+ datos.append(["", "", caso, factores[j]])
|
|
|
|
|
+
|
|
|
|
|
+ printProgressBar(i + 1, num_combos, prefix="Progreso:", suffix="Completado", length=50)
|
|
|
|
|
+
|
|
|
|
|
+ # --- Crear Excel con formato idéntico a SAP2000 ---
|
|
|
|
|
+ wb = Workbook()
|
|
|
|
|
+ ws = wb.active
|
|
|
|
|
+ ws.title = "Combinaciones"
|
|
|
|
|
+
|
|
|
|
|
+ # 1. Título
|
|
|
|
|
+ ws['A1'] = "TABLE: Combination Definitions"
|
|
|
|
|
+ ws['A1'].font = Font(name="Arial Narrow", size=12, bold=True)
|
|
|
|
|
+ ws['A1'].alignment = Alignment(horizontal="center")
|
|
|
|
|
+ ws.merge_cells('A1:D1')
|
|
|
|
|
+
|
|
|
|
|
+ # 2. Cabeceras (azul marino SAP2000)
|
|
|
|
|
+ cabeceras = ["ComboName", "ComboType", "CaseName", "ScaleFactor"]
|
|
|
|
|
+ for c, texto in enumerate(cabeceras, 1):
|
|
|
|
|
+ cell = ws.cell(row=2, column=c, value=texto)
|
|
|
|
|
+ cell.font = Font(name="Arial Narrow", bold=True, color="FFFFFF")
|
|
|
|
|
+ cell.fill = PatternFill(start_color=AZUL_SAP, end_color=AZUL_SAP, fill_type="solid")
|
|
|
|
|
+ cell.alignment = Alignment(horizontal="center")
|
|
|
|
|
+
|
|
|
|
|
+ # 3. Tipos de datos (amarillo SAP2000)
|
|
|
|
|
+ tipos = ["Text", "Text", "Text", "Unitless"]
|
|
|
|
|
+ for c, texto in enumerate(tipos, 1):
|
|
|
|
|
+ cell = ws.cell(row=3, column=c, value=texto)
|
|
|
|
|
+ cell.font = Font(name="Arial Narrow", color="000000")
|
|
|
|
|
+ cell.fill = PatternFill(start_color=AMARILLO_SAP, end_color=AMARILLO_SAP, fill_type="solid")
|
|
|
|
|
+ cell.alignment = Alignment(horizontal="center")
|
|
|
|
|
+
|
|
|
|
|
+ # 4. Datos
|
|
|
|
|
+ for r, fila in enumerate(datos, start=4):
|
|
|
|
|
+ for c, valor in enumerate(fila, 1):
|
|
|
|
|
+ cell = ws.cell(row=r, column=c, value=valor)
|
|
|
|
|
+ cell.font = Font(name="Arial Narrow")
|
|
|
|
|
+
|
|
|
|
|
+ # Autoajustar columnas según el contenido (excluyendo la primera fila que está fusionada)
|
|
|
|
|
+ column_widths = {1: 18, 2: 12, 3: 25, 4: 12} # Anchos por defecto
|
|
|
|
|
+
|
|
|
|
|
+ for row in ws.iter_rows(min_row=2, max_row=ws.max_row): # Comienza desde fila 2
|
|
|
|
|
+ for col_idx, cell in enumerate(row, 1):
|
|
|
|
|
+ if cell.value:
|
|
|
|
|
+ cell_len = len(str(cell.value))
|
|
|
|
|
+ if col_idx in column_widths:
|
|
|
|
|
+ column_widths[col_idx] = max(column_widths[col_idx], cell_len)
|
|
|
|
|
+
|
|
|
|
|
+ for col_idx, width in column_widths.items():
|
|
|
|
|
+ ws.column_dimensions[get_column_letter(col_idx)].width = width
|
|
|
|
|
+ # Guardar
|
|
|
|
|
+ wb.save(archivo_salida)
|
|
|
|
|
+ print(f"\nCOMBINACIONES EXTRAÍDAS CORRECTAMENTE")
|
|
|
|
|
+ print(f"Archivo: {archivo_salida}")
|
|
|
|
|
+ print("Formato 100% idéntico al reporte oficial de SAP2000\n")
|