extraer_comb.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. # ===================================================================
  2. # extraer_combos_sap.py
  3. # Función standalone para extraer combinaciones de SAP2000
  4. # ===================================================================
  5. import os
  6. import tkinter as tk
  7. from tkinter.filedialog import asksaveasfilename
  8. from openpyxl import Workbook
  9. from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
  10. from openpyxl.utils import get_column_letter
  11. # Colores exactos de SAP2000
  12. AZUL_TITULO = "33CCCC" # Azul oscurito título
  13. AZUL_SAP = "CCFFFF" # Azul marino cabecera
  14. # Barra de progreso (la misma que usas en el script principal)
  15. def printProgressBar(iteration, total, prefix='', suffix='', decimals=1, length=50, fill='█'):
  16. percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
  17. filledLength = int(length * iteration // total)
  18. bar = fill * filledLength + '-' * (length - filledLength)
  19. print(f'\r{prefix} |{bar}| {percent}% {suffix}', end="")
  20. if iteration == total:
  21. print()
  22. def extraer_combinaciones_a_excel(SapModel, ruta_excel_origen=None):
  23. """
  24. Extrae todas las combinaciones de SAP2000 y las guarda en Excel
  25. con el formato EXACTO del reporte oficial de SAP2000.
  26. Parámetros:
  27. SapModel: objeto SAP2000 ya conectado
  28. ruta_excel_origen: (opcional) ruta del Excel original para sugerir nombre y carpeta
  29. """
  30. # --- Ventana para guardar ---
  31. root = tk.Tk()
  32. root.withdraw()
  33. root.attributes('-topmost', True)
  34. # Sugerir nombre y carpeta inteligente
  35. if ruta_excel_origen and os.path.exists(ruta_excel_origen):
  36. carpeta = os.path.dirname(ruta_excel_origen)
  37. nombre_base = os.path.splitext(os.path.basename(ruta_excel_origen))[0]
  38. nombre_sugerido = f"{nombre_base}_COMBINACIONES_SAP2000.xlsx"
  39. initialfile = nombre_sugerido
  40. else:
  41. initialfile = "COMBINACIONES_SAP2000.xlsx"
  42. archivo_salida = asksaveasfilename(
  43. initialfile=initialfile,
  44. defaultextension=".xlsx",
  45. filetypes=[("Excel files", "*.xlsx")],
  46. title="Guardar combinaciones (formato SAP2000)"
  47. )
  48. root.destroy()
  49. if not archivo_salida:
  50. print("\nExportación cancelada por el usuario.")
  51. return
  52. # --- Extraer combinaciones ---
  53. ret = SapModel.RespCombo.GetNameList()
  54. num_combos = ret[0]
  55. combo_names = ret[1]
  56. datos = []
  57. print(f"\nExtrayendo {num_combos} combinaciones con formato oficial SAP2000...")
  58. for i, combo_name in enumerate(combo_names):
  59. tipo = SapModel.RespCombo.GetTypeOAPI(combo_name)[0]
  60. tipo_texto = "Linear Add" if tipo == 0 else "Envelope" if tipo == 1 else "Other"
  61. casos = SapModel.RespCombo.GetCaseList(combo_name)
  62. nombres_casos = casos[2]
  63. factores = casos[3]
  64. if len(nombres_casos) == 0:
  65. datos.append([combo_name, tipo_texto, "", ""])
  66. else:
  67. for j, caso in enumerate(nombres_casos):
  68. if j == 0:
  69. datos.append([combo_name, tipo_texto, caso, factores[j]])
  70. else:
  71. datos.append(["", "", caso, factores[j]])
  72. printProgressBar(i + 1, num_combos, prefix="Progreso:", suffix="Completado", length=50)
  73. # --- Crear Excel con formato idéntico a SAP2000 ---
  74. wb = Workbook()
  75. ws = wb.active
  76. ws.title = "Combinaciones"
  77. # 1. Título
  78. ws['A1'] = "TABLE: Combination Definitions"
  79. ws['A1'].font = Font(name="Arial Narrow", size=11, bold=True)
  80. ws['A1'].alignment = Alignment(horizontal="center")
  81. ws['A1'].fill = PatternFill(start_color=AZUL_TITULO, end_color=AZUL_TITULO, fill_type="solid")
  82. ws.merge_cells('A1:D1')
  83. # 2. Cabeceras (azul marino SAP2000)
  84. cabeceras = ["ComboName", "ComboType", "CaseName", "ScaleFactor"]
  85. for c, texto in enumerate(cabeceras, 1):
  86. cell = ws.cell(row=2, column=c, value=texto)
  87. cell.font = Font(name="Arial Narrow", bold=True, color="000000", size=10)
  88. cell.fill = PatternFill(start_color=AZUL_SAP, end_color=AZUL_SAP, fill_type="solid")
  89. cell.alignment = Alignment(horizontal="center")
  90. # 3. Tipos de datos (amarillo SAP2000)
  91. tipos = ["Text", "Text", "Text", "Unitless"]
  92. for c, texto in enumerate(tipos, 1):
  93. cell = ws.cell(row=3, column=c, value=texto)
  94. cell.font = Font(name="Arial Narrow", color="000000", size=10)
  95. cell.fill = PatternFill(start_color=AZUL_SAP, end_color=AZUL_SAP, fill_type="solid")
  96. cell.alignment = Alignment(horizontal="center")
  97. # 4. Datos
  98. for r, fila in enumerate(datos, start=4):
  99. for c, valor in enumerate(fila, 1):
  100. cell = ws.cell(row=r, column=c, value=valor)
  101. cell.font = Font(name="Arial Narrow", size=10)
  102. # Aplicar borde fino a todas las celdas
  103. thin_border = Border(left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin'))
  104. for row in ws.iter_rows():
  105. for cell in row:
  106. cell.border = thin_border
  107. # Autoajustar columnas según el contenido (excluyendo la primera fila que está fusionada)
  108. column_widths = {1: 18, 2: 12, 3: 25, 4: 12} # Anchos por defecto
  109. for row in ws.iter_rows(min_row=2, max_row=ws.max_row): # Comienza desde fila 2
  110. for col_idx, cell in enumerate(row, 1):
  111. if cell.value:
  112. cell_len = len(str(cell.value))
  113. if col_idx in column_widths:
  114. column_widths[col_idx] = max(column_widths[col_idx], cell_len)
  115. for col_idx, width in column_widths.items():
  116. ws.column_dimensions[get_column_letter(col_idx)].width = width
  117. # Guardar
  118. wb.save(archivo_salida)
  119. print(f"\nCOMBINACIONES EXTRAÍDAS CORRECTAMENTE")
  120. print(f"Archivo: {archivo_salida}")