| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- # ===================================================================
- # 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, Border, Side
- from openpyxl.utils import get_column_letter
- # Colores exactos de SAP2000
- AZUL_TITULO = "33CCCC" # Azul oscurito título
- AZUL_SAP = "CCFFFF" # Azul marino cabecera
- # 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 = 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=11, bold=True)
- ws['A1'].alignment = Alignment(horizontal="center")
- ws['A1'].fill = PatternFill(start_color=AZUL_TITULO, end_color=AZUL_TITULO, fill_type="solid")
- 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="000000", size=10)
- 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", size=10)
- cell.fill = PatternFill(start_color=AZUL_SAP, end_color=AZUL_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", size=10)
- # Aplicar borde fino a todas las celdas
- thin_border = Border(left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin'))
- for row in ws.iter_rows():
- for cell in row:
- cell.border = thin_border
- # 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}")
|