فهرست منبع

app pseudo terminada, falta añadir multiples 'si y solo si' y embeber el excel directamente desde python

dacowars 2 هفته پیش
والد
کامیت
555c9e8266
2فایلهای تغییر یافته به همراه314 افزوده شده و 8 حذف شده
  1. 41 3
      Comb_acciones.py
  2. 273 5
      extraer_comb.py

+ 41 - 3
Comb_acciones.py

@@ -12,7 +12,7 @@ import math
 import numpy as np
 import numpy as np
 import warnings
 import warnings
 warnings.filterwarnings('ignore', category=UserWarning, module='openpyxl')
 warnings.filterwarnings('ignore', category=UserWarning, module='openpyxl')
-from extraer_comb import extraer_combinaciones_a_excel
+from extraer_comb import *
 import threading
 import threading
 import time
 import time
 
 
@@ -190,7 +190,7 @@ try:
     helper = helper.QueryInterface(comtypes.gen.SAP2000v1.cHelper)
     helper = helper.QueryInterface(comtypes.gen.SAP2000v1.cHelper)
     mySapObject = helper.GetObject("CSI.SAP2000.API.SapObject")
     mySapObject = helper.GetObject("CSI.SAP2000.API.SapObject")
     SapModel = mySapObject.SapModel
     SapModel = mySapObject.SapModel
-    SapModel.SetModelisLocked(False)
+    if not SapModel.GetModelisLocked(): SapModel.SetModelisLocked(False)
 
 
 except TimeoutException as exc:
 except TimeoutException as exc:
     messagebox.showerror(
     messagebox.showerror(
@@ -683,7 +683,7 @@ def crear_ventana_configuracion():
     """Crea una ventana gráfica para configuración inicial"""
     """Crea una ventana gráfica para configuración inicial"""
     ventana = tk.Tk()
     ventana = tk.Tk()
     ventana.title("Configuración de Combinaciones")
     ventana.title("Configuración de Combinaciones")
-    ventana.geometry("600x600")
+    ventana.geometry("600x800")
     ventana.attributes('-topmost', True)
     ventana.attributes('-topmost', True)
     script_dir = os.path.dirname(os.path.abspath(__file__))
     script_dir = os.path.dirname(os.path.abspath(__file__))
     icon_path = os.path.join(script_dir, 'AYRE.ico')
     icon_path = os.path.join(script_dir, 'AYRE.ico')
@@ -767,6 +767,40 @@ def crear_ventana_configuracion():
     boton_extraer = tk.Button(ventana, text="Extraer datos", command=on_extraer, font=("Arial", 11), bg="#FF9800", fg="white", padx=10, pady=5)
     boton_extraer = tk.Button(ventana, text="Extraer datos", command=on_extraer, font=("Arial", 11), bg="#FF9800", fg="white", padx=10, pady=5)
     boton_extraer.pack(pady=20)
     boton_extraer.pack(pady=20)
 
 
+    # Boton extraer flechas
+    def on_deflection():
+        extraer_flechas(SapModel, var_excel.get(), var_flechas.get())
+
+    # Frame para flechas
+    frame_flechas = tk.Frame(ventana)
+    frame_flechas.pack(anchor=tk.CENTER, padx=20, pady=10)
+    var_flechas = tk.StringVar(value="1. ENV ELU P")
+    combo_flechas = tk.ttk.Combobox(frame_flechas, textvariable=var_flechas,
+                                    values=["1. ENV ELU P", "2. ENV ELU ACC", "3. ENV ELU SIS", "4. ENV ELS C", "5. ENV ELS F", "6. ENV ELS CP"], 
+                                    state="readonly", width=15)
+    combo_flechas.pack(side=tk.RIGHT, padx=5)
+
+    boton_deflection = tk.Button(ventana, text="Extraer flechas", command=on_deflection, font=("Arial", 11), bg="#2196F3", fg="white", padx=10, pady=5)
+    boton_deflection.pack(pady=20)
+
+
+
+    # Boton extraer esfuerzos
+    def on_esfuerzos():
+        extraer_esfuerzos(SapModel, var_excel.get(), var_flechas.get())
+
+    # Frame para esfuerzos
+    frame_esfuerzos = tk.Frame(ventana)
+    frame_esfuerzos.pack(anchor=tk.CENTER, padx=20, pady=10)
+    var_esfuerzos = tk.StringVar(value="1. ENV ELU P")
+    combo_esfuerzos = tk.ttk.Combobox(frame_esfuerzos, textvariable=var_esfuerzos,
+                                    values=["1. ENV ELU P", "2. ENV ELU ACC", "3. ENV ELU SIS", "4. ENV ELS C", "5. ENV ELS F", "6. ENV ELS CP"], 
+                                    state="readonly", width=15)
+    combo_esfuerzos.pack(side=tk.RIGHT, padx=5)
+    boton_esfuerzos = tk.Button(ventana, text="Extraer esfuerzos", command=on_esfuerzos, font=("Arial", 11), bg="#2196F3", fg="white", padx=10, pady=5)
+    boton_esfuerzos.pack(pady=20)
+
+
     def comprobacion_SAP_cerrado():
     def comprobacion_SAP_cerrado():
         try:    
         try:    
             ret = SapModel.Analyze.GetCaseStatus()
             ret = SapModel.Analyze.GetCaseStatus()
@@ -774,8 +808,12 @@ def crear_ventana_configuracion():
                 estados = ret[2]
                 estados = ret[2]
                 if any(estado == 4 for estado in estados):
                 if any(estado == 4 for estado in estados):
                     boton_extraer.config(state=tk.NORMAL)
                     boton_extraer.config(state=tk.NORMAL)
+                    boton_deflection.config(state=tk.NORMAL)
+                    boton_esfuerzos.config(state=tk.NORMAL)
                 else: 
                 else: 
                     boton_extraer.config(state=tk.DISABLED)
                     boton_extraer.config(state=tk.DISABLED)
+                    boton_deflection.config(state=tk.DISABLED)
+                    boton_esfuerzos.config(state=tk.DISABLED)
         except (comtypes.COMError, Exception) as e:
         except (comtypes.COMError, Exception) as e:
             sys.exit(0)  # Cierra la aplicación si SAP2000 está cerrado
             sys.exit(0)  # Cierra la aplicación si SAP2000 está cerrado
 
 

+ 273 - 5
extraer_comb.py

@@ -7,7 +7,7 @@ import os
 import tkinter as tk
 import tkinter as tk
 from tkinter.filedialog import asksaveasfilename
 from tkinter.filedialog import asksaveasfilename
 from openpyxl import Workbook
 from openpyxl import Workbook
-from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
+from openpyxl.styles import Font, PatternFill, Alignment, Border, Side, NamedStyle
 from openpyxl.utils import get_column_letter
 from openpyxl.utils import get_column_letter
 
 
 # Colores exactos de SAP2000
 # Colores exactos de SAP2000
@@ -40,7 +40,6 @@ def extraer_combinaciones_a_excel(SapModel, ruta_excel_origen=None):
 
 
     # Sugerir nombre y carpeta inteligente
     # Sugerir nombre y carpeta inteligente
     if ruta_excel_origen and os.path.exists(ruta_excel_origen):
     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_base = os.path.splitext(os.path.basename(ruta_excel_origen))[0]
         nombre_sugerido = f"{nombre_base}_COMBINACIONES_SAP2000.xlsx"
         nombre_sugerido = f"{nombre_base}_COMBINACIONES_SAP2000.xlsx"
         initialfile = nombre_sugerido
         initialfile = nombre_sugerido
@@ -65,7 +64,7 @@ def extraer_combinaciones_a_excel(SapModel, ruta_excel_origen=None):
     combo_names = ret[1]
     combo_names = ret[1]
 
 
     datos = []
     datos = []
-    print(f"\nExtrayendo {num_combos} combinaciones con formato oficial SAP2000...")
+
 
 
     for i, combo_name in enumerate(combo_names):
     for i, combo_name in enumerate(combo_names):
         tipo = SapModel.RespCombo.GetTypeOAPI(combo_name)[0]
         tipo = SapModel.RespCombo.GetTypeOAPI(combo_name)[0]
@@ -140,5 +139,274 @@ def extraer_combinaciones_a_excel(SapModel, ruta_excel_origen=None):
         ws.column_dimensions[get_column_letter(col_idx)].width = width
         ws.column_dimensions[get_column_letter(col_idx)].width = width
     # Guardar
     # Guardar
     wb.save(archivo_salida)
     wb.save(archivo_salida)
-    print(f"\nCOMBINACIONES EXTRAÍDAS CORRECTAMENTE")
-    print(f"Archivo: {archivo_salida}")
+    
+
+
+
+def extraer_flechas(SapModel, ruta_excel_origen=None, var_flechas=None):
+    """
+    Función placeholder para extraer flechas.
+    Actualmente no implementada.
+    """
+    # --- 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):
+        nombre_base = os.path.splitext(os.path.basename(ruta_excel_origen))[0]
+        nombre_sugerido = f"{nombre_base}_DESPLAZAMIENTOS_SAP2000.xlsx"
+        initialfile = nombre_sugerido
+    else:
+        initialfile = "DESPLAZAMIENTOS_SAP2000.xlsx"
+
+    archivo_salida = asksaveasfilename(
+        initialfile=initialfile,
+        defaultextension=".xlsx",
+        filetypes=[("Excel files", "*.xlsx")],
+        title="Guardar desplazamientos (formato SAP2000)"
+    )
+    root.destroy()
+
+    if not archivo_salida:
+        print("\nExportación cancelada por el usuario.")
+        return
+    
+    
+    # Obtener desplazamientos en nudos
+   
+    FieldKeyList = []
+    GroupName = 'All'
+    TableVersion = 1
+    FieldsKeysIncluded = []
+    NumberRecords = 1
+    TableData = []
+
+    SapModel.SetPresentUnits(9)  # Unidades niutons milimetos
+    ret = SapModel.Results.Setup.DeselectAllCasesAndCombosForOutput()
+    ret = SapModel.Results.Setup.SetComboSelectedForOutput(var_flechas)
+
+    ret = SapModel.DatabaseTables.GetTableforDisplayArray("Joint Displacements", FieldKeyList, GroupName, 
+                                                    TableVersion, FieldsKeysIncluded, NumberRecords, TableData)
+
+    datos = []
+
+    for i in range(int(len(ret[4])/10)):
+      datos.append([ret[4][i*10], ret[4][i*10+1], ret[4][i*10+2], ret[4][i*10+3], ret[4][i*10+4], 
+                    ret[4][i*10+5], ret[4][i*10+6], ret[4][i*10+7], ret[4][i*10+8], ret[4][i*10+9]])
+
+
+
+    # --- Crear Excel con formato idéntico a SAP2000 ---
+    wb = Workbook()
+    ws = wb.active
+    ws.title = "Desplazamientos"
+
+    #se ajustan los decimales 
+
+    flecha_style = NamedStyle(name="flecha_style", number_format="0.00", font=Font(name="Arial Narrow", size=10))
+    giro_style = NamedStyle(name="giro_style", number_format="0.0000", font=Font(name="Arial Narrow", size=10))
+
+    wb.add_named_style(flecha_style)
+    wb.add_named_style(giro_style)
+
+    # 1. Título
+    ws['A1'] = "TABLE:  Joint Displacements"
+    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:J1')
+
+    # 2. Cabeceras (azul marino SAP2000)
+    cabeceras = ret[2]
+    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", "Text", "Length (mm)", "Length (mm)", "Length (mm)",  "Angle", "Angle", "Angle"]
+    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)
+            if c > 4: 
+                try:
+                    cell.value = float(valor.replace(',', '.'))  # Asegurarse de que es float
+                except ValueError:
+                    cell.value = valor
+            cell.font = Font(name="Arial Narrow", size=10)
+    
+    num_rows = ws.max_row
+    for row in range(4, num_rows + 1):
+        for col in ['E', 'F', 'G']:  # UX, UY, UZ (flechas)
+            ws[f'{col}{row}'].style = flecha_style
+        for col in ['H', 'I', 'J']:  # RX, RY, RZ (giros)
+            ws[f'{col}{row}'].style = giro_style
+
+            
+    # 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, 5: 12, 6: 12, 7: 12, 8: 12, 9: 12, 10: 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)
+
+
+
+
+def extraer_esfuerzos(SapModel, ruta_excel_origen=None, var_esfuerzos=None):
+    """
+    Función placeholder para extraer flechas.
+    Actualmente no implementada.
+    """
+    # --- 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):
+        nombre_base = os.path.splitext(os.path.basename(ruta_excel_origen))[0]
+        nombre_sugerido = f"{nombre_base}_ESFUERZOS_SAP2000.xlsx"
+        initialfile = nombre_sugerido
+    else:
+        initialfile = "ESFUERZOS_SAP2000.xlsx"
+
+    archivo_salida = asksaveasfilename(
+        initialfile=initialfile,
+        defaultextension=".xlsx",
+        filetypes=[("Excel files", "*.xlsx")],
+        title="Guardar esfuerzos (formato SAP2000)"
+    )
+    root.destroy()
+
+    if not archivo_salida:
+        print("\nExportación cancelada por el usuario.")
+        return
+    
+    
+    # Obtener desplazamientos en nudos
+   
+    FieldKeyList = []
+    GroupName = 'All'
+    TableVersion = 1
+    FieldsKeysIncluded = []
+    NumberRecords = 1
+    TableData = []
+
+    SapModel.SetPresentUnits(6)  # Unidades niutons milimetos
+    ret = SapModel.Results.Setup.DeselectAllCasesAndCombosForOutput()
+    ret = SapModel.Results.Setup.SetComboSelectedForOutput(var_esfuerzos)
+
+    ret = SapModel.DatabaseTables.GetTableforDisplayArray("Element Forces - Frames", FieldKeyList, GroupName, 
+                                                    TableVersion, FieldsKeysIncluded, NumberRecords, TableData)
+
+    datos = []
+
+    for i in range(int(len(ret[4])/13)):
+      datos.append([ret[4][i*13], ret[4][i*13+1], ret[4][i*13+2], ret[4][i*13+3], ret[4][i*13+4], 
+                    ret[4][i*13+5], ret[4][i*13+6], ret[4][i*13+7], ret[4][i*13+8], ret[4][i*13+9],
+                    ret[4][i*13+10], ret[4][i*13+11], ret[4][i*13+12]])
+
+
+    # --- Crear Excel con formato idéntico a SAP2000 ---
+    wb = Workbook()
+    ws = wb.active
+    ws.title = "Desplazamientos"
+
+    #se ajustan los decimales 
+
+    flecha_style = NamedStyle(name="flecha_style", number_format="0.00", font=Font(name="Arial Narrow", size=10))
+    giro_style = NamedStyle(name="giro_style", number_format="0.0000", font=Font(name="Arial Narrow", size=10))
+
+    wb.add_named_style(flecha_style)
+    wb.add_named_style(giro_style)
+
+    # 1. Título
+    ws['A1'] = "TABLE:  Joint Displacements"
+    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:M1')
+
+    # 2. Cabeceras (azul marino SAP2000)
+    cabeceras = ret[2]
+    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", "m", "Text", "Text", "Text", "kN", "kN",  "kN", "kNm", "kNm", "kNm", "Text", "Text"]
+    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)
+            if ((c > 5) and (c < 12)) or (c==2): 
+                try:
+                    cell.value = float(valor.replace(',', '.'))  # Asegurarse de que es float
+                except ValueError:
+                    cell.value = valor
+            cell.font = Font(name="Arial Narrow", size=10)
+    
+    num_rows = ws.max_row
+    for row in range(4, num_rows + 1):
+        for col in ['B','F', 'F', 'G', 'H', 'I', 'J', 'K']:  # UX, UY, UZ (flechas)
+            ws[f'{col}{row}'].style = flecha_style
+
+            
+    # 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, 5: 12, 6: 12, 7: 12, 8: 12, 9: 12, 10: 12, 11: 12, 12: 12, 13: 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)
+