extraer_comb.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. # ===================================================================
  2. # extraer_combos_sap.py
  3. # Función standalone para extraer combinaciones de SAP2000 con formato 100% idéntico al reporte oficial
  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
  10. from openpyxl.utils import get_column_letter
  11. # Colores exactos de SAP2000
  12. AZUL_SAP = "000080" # Azul marino cabecera
  13. AMARILLO_SAP = "FFFF00" # Amarillo fila de tipos
  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 = os.path.join(carpeta, 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=12, bold=True)
  80. ws['A1'].alignment = Alignment(horizontal="center")
  81. ws.merge_cells('A1:D1')
  82. # 2. Cabeceras (azul marino SAP2000)
  83. cabeceras = ["ComboName", "ComboType", "CaseName", "ScaleFactor"]
  84. for c, texto in enumerate(cabeceras, 1):
  85. cell = ws.cell(row=2, column=c, value=texto)
  86. cell.font = Font(name="Arial Narrow", bold=True, color="FFFFFF")
  87. cell.fill = PatternFill(start_color=AZUL_SAP, end_color=AZUL_SAP, fill_type="solid")
  88. cell.alignment = Alignment(horizontal="center")
  89. # 3. Tipos de datos (amarillo SAP2000)
  90. tipos = ["Text", "Text", "Text", "Unitless"]
  91. for c, texto in enumerate(tipos, 1):
  92. cell = ws.cell(row=3, column=c, value=texto)
  93. cell.font = Font(name="Arial Narrow", color="000000")
  94. cell.fill = PatternFill(start_color=AMARILLO_SAP, end_color=AMARILLO_SAP, fill_type="solid")
  95. cell.alignment = Alignment(horizontal="center")
  96. # 4. Datos
  97. for r, fila in enumerate(datos, start=4):
  98. for c, valor in enumerate(fila, 1):
  99. cell = ws.cell(row=r, column=c, value=valor)
  100. cell.font = Font(name="Arial Narrow")
  101. # Autoajustar columnas según el contenido (excluyendo la primera fila que está fusionada)
  102. column_widths = {1: 18, 2: 12, 3: 25, 4: 12} # Anchos por defecto
  103. for row in ws.iter_rows(min_row=2, max_row=ws.max_row): # Comienza desde fila 2
  104. for col_idx, cell in enumerate(row, 1):
  105. if cell.value:
  106. cell_len = len(str(cell.value))
  107. if col_idx in column_widths:
  108. column_widths[col_idx] = max(column_widths[col_idx], cell_len)
  109. for col_idx, width in column_widths.items():
  110. ws.column_dimensions[get_column_letter(col_idx)].width = width
  111. # Guardar
  112. wb.save(archivo_salida)
  113. print(f"\nCOMBINACIONES EXTRAÍDAS CORRECTAMENTE")
  114. print(f"Archivo: {archivo_salida}")
  115. print("Formato 100% idéntico al reporte oficial de SAP2000\n")