Bläddra i källkod

refactorizado todo el codigo, basado en una interfaz

dacowars 2 veckor sedan
förälder
incheckning
4b2ae96b70
2 ändrade filer med 475 tillägg och 598 borttagningar
  1. 474 597
      Comb_acciones.py
  2. 1 1
      extraer_comb.py

+ 474 - 597
Comb_acciones.py

@@ -6,13 +6,15 @@ pd.set_option('future.no_silent_downcasting', True)
 import itertools
 import tkinter as tk
 from tkinter import *
-from tkinter import ttk
+from tkinter import ttk, messagebox, scrolledtext
 from tkinter.filedialog import askopenfilename
 import math
 import numpy as np
 import warnings
 warnings.filterwarnings('ignore', category=UserWarning, module='openpyxl')
 from extraer_comb import extraer_combinaciones_a_excel
+import threading
+import time
 
 
 
@@ -50,6 +52,8 @@ def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1,
             print('\r' + ' ' * 150 + '\r', end = '')
         else:
             print()
+    time.sleep(0.01)
+
 
 
 #diccionario donde se encuentran todos los coef de comb acciones de las normas
@@ -171,14 +175,33 @@ normas = {
     }
 }
 
+class TimeoutException(Exception):
+    pass
+
+def raise_timeout():
+    raise TimeoutException()
+
+timer = threading.Timer(20.0, raise_timeout) #se crea un timer de 20 segundos
+timer.start()
+
+try:
+    #Conexion con SAP2000
+    helper = comtypes.client.CreateObject('SAP2000v1.Helper')
+    helper = helper.QueryInterface(comtypes.gen.SAP2000v1.cHelper)
+    mySapObject = helper.GetObject("CSI.SAP2000.API.SapObject")
+    SapModel = mySapObject.SapModel
+    SapModel.SetModelisLocked(False)
+
+except TimeoutException as exc:
+    messagebox.showerror(
+        "Error",
+        "No se encuentra una instancia de SAP2000 abierta. Por favor, abra SAP2000 e intente de nuevo."
+    )
+    sys.exit(1)
 
-#Conexion con SAP2000
+finally:
+    timer.cancel()
 
-helper = comtypes.client.CreateObject('SAP2000v1.Helper')
-helper = helper.QueryInterface(comtypes.gen.SAP2000v1.cHelper)
-mySapObject = helper.GetObject("CSI.SAP2000.API.SapObject")
-SapModel = mySapObject.SapModel
-SapModel.SetModelisLocked(False)
 
 #se pregunta si se desea borrar todo lo que hay en el SAP
 
@@ -205,173 +228,58 @@ def borrar_patrones_carga():
             printProgressBar(patternNames[1].index(name)+1, patternNames[0], prefix = 'Borrando patrones de carga existentes:', suffix = 'Completado', length = 50)
 
 
-def crear_ventana_configuracion():
-    """Crea una ventana gráfica para configuración inicial"""
-    resultado = {'borrar_combos': False, 'borrar_cargas': False, 'norma': 'IAPF', 'vias': '1'}
-    
-    ventana = tk.Tk()
-    ventana.title("Configuración de Combinaciones")
-    ventana.geometry("400x300")
-    ventana.attributes('-topmost', True)
-    script_dir = os.path.dirname(os.path.abspath(__file__))
-    icon_path = os.path.join(script_dir, 'AYRE.ico')
-    ventana.iconbitmap(icon_path)
-
-    
-    # Título
-    titulo = tk.Label(ventana, text="Configuración Inicial", font=("Arial", 14, "bold"))
-    titulo.pack(pady=10)
-    
-    # Checkbox 1: Borrar combinaciones
-    var_combos = tk.BooleanVar(value=True)
-    check_combos = tk.Checkbutton(ventana, text="Borrar combinaciones existentes", variable=var_combos, font=("Arial", 10))
-    check_combos.pack(anchor=tk.W, padx=20, pady=5)
-    
-    # Checkbox 2: Borrar cargas
-    var_cargas = tk.BooleanVar(value=True)
-    check_cargas = tk.Checkbutton(ventana, text="Borrar cargas existentes", variable=var_cargas, font=("Arial", 10))
-    check_cargas.pack(anchor=tk.W, padx=20, pady=5)
-    
-    # Frame para norma
-    frame_norma = tk.Frame(ventana)
-    frame_norma.pack(anchor=tk.W, padx=20, pady=10)
-    label_norma = tk.Label(frame_norma, text="Norma:", font=("Arial", 10))
-    label_norma.pack(side=tk.LEFT, padx=5)
-    var_norma = tk.StringVar(value="IAPF")
-    combo_norma = tk.ttk.Combobox(frame_norma, textvariable=var_norma, values=["IAPF", "IAP"], state="readonly", width=15)
-    combo_norma.pack(side=tk.LEFT, padx=5)
-    
-    # Frame para vías
-    frame_vias = tk.Frame(ventana)
-    frame_vias.pack(anchor=tk.W, padx=20, pady=10)
-    label_vias = tk.Label(frame_vias, text="Vías cargadas:", font=("Arial", 10))
-    label_vias.pack(side=tk.LEFT, padx=5)
-    var_vias = tk.StringVar(value="1")
-    combo_vias = tk.ttk.Combobox(frame_vias, textvariable=var_vias, values=["1", "2", "3", "Más de 3"], state="readonly", width=15)
-    combo_vias.pack(side=tk.LEFT, padx=5)
-    
-    
-    
-    # Botón OK
-    def on_ok():
-        resultado['borrar_combos'] = var_combos.get()
-        resultado['borrar_cargas'] = var_cargas.get()
-        resultado['norma'] = var_norma.get()
-        resultado['vias'] = var_vias.get()
-        ventana.destroy()
-    
-    boton_ok = tk.Button(ventana, text="Aceptar", command=on_ok, font=("Arial", 11), bg="#4CAF50", fg="white", padx=20, pady=10)
-    boton_ok.pack(pady=20)
-    
-    ventana.mainloop()
-    return resultado
-
-
-# Mostrar ventana de configuración
-config = crear_ventana_configuracion()
+def extraer_datos_excel(ruta_excel):
 
-# Asignar valores
-if config['borrar_combos']:
-    borrar_combos_existentes()
+    compatibilidades_df = pd.read_excel(ruta_excel,
+                                sheet_name='Compatibilidades')
 
-if config['borrar_cargas']:
-    borrar_load_cases()
-    borrar_patrones_carga()
+    compatibilidades_df = compatibilidades_df.astype(object)
 
-norma_proyecto = config['norma']
-vias_cargadas = config['vias']
+    restricciones_df = pd.read_excel(ruta_excel,
+                                sheet_name='Restricciones')
 
 
+    #Limpieza de filas vacias
 
-#Extraccion de datos del excel
+    x, y = compatibilidades_df.shape
 
-# Crear ventana para el diálogo de selección con icono
-root = tk.Tk()
-root.withdraw()  # Oculta la ventana
-script_dir = os.path.dirname(os.path.abspath(__file__))
-try:
-    icon_path = os.path.join(script_dir, 'AYRE.ico')
-    root.iconbitmap(icon_path)
-except:
-    pass
-root.attributes('-topmost', True)
-ruta_excel = askopenfilename(parent=root)
-root.destroy()
-
-#ruta_excel = "C:/Users/Daniel.p/Documents/14. Ay-A 0042 Foso ataque empuje tubos y cimentaciones grua ( PALENCIA)/1. MEMORIA/Comb_acciones.xlsx"
-
-compatibilidades_df = pd.read_excel(ruta_excel,
-                              sheet_name='Compatibilidades')
-
-compatibilidades_df = compatibilidades_df.astype(object)
-
-restricciones_df = pd.read_excel(ruta_excel,
-                              sheet_name='Restricciones')
+    for i in range(x):
+        if (compatibilidades_df.loc[i, compatibilidades_df.columns.values[0]] == 0):
+            compatibilidades_df=compatibilidades_df.drop(i)
 
 
-#Limpieza de filas vacias
 
-x, y = compatibilidades_df.shape
+    for i in range(y-1, 0, -1):
+        col_name = compatibilidades_df.columns.values[i]
+        if (isinstance(compatibilidades_df[col_name].name, int)):
+            compatibilidades_df = compatibilidades_df.drop(col_name, axis=1)
+        elif isinstance(col_name, str) and col_name.startswith("0"):
+            compatibilidades_df = compatibilidades_df.drop(col_name, axis=1) 
 
-for i in range(x):
-    if (compatibilidades_df.loc[i, compatibilidades_df.columns.values[0]] == 0):
-        compatibilidades_df=compatibilidades_df.drop(i)
 
+    x, y = compatibilidades_df.shape
 
+    for i in range(1, x+1):
+        for j in range(i-1):
+            if not isinstance(compatibilidades_df.loc[j, compatibilidades_df.columns.values[i]], str):
+                if math.isnan(compatibilidades_df.loc[j, compatibilidades_df.columns.values[i]]):
+                    compatibilidades_df.loc[j, compatibilidades_df.columns.values[i]] = 'x'
 
-for i in range(y-1, 0, -1):
-    col_name = compatibilidades_df.columns.values[i]
-    if (isinstance(compatibilidades_df[col_name].name, int)):
-        compatibilidades_df = compatibilidades_df.drop(col_name, axis=1)
-    elif isinstance(col_name, str) and col_name.startswith("0"):
-        compatibilidades_df = compatibilidades_df.drop(col_name, axis=1) 
 
 
-x, y = compatibilidades_df.shape
+    #cambio de los valores Nan por 0
+    compatibilidades_df = compatibilidades_df.fillna(0).infer_objects(copy=False)
 
-for i in range(1, x+1):
-    for j in range(i-1):
-        if not isinstance(compatibilidades_df.loc[j, compatibilidades_df.columns.values[i]], str):
-            if math.isnan(compatibilidades_df.loc[j, compatibilidades_df.columns.values[i]]):
-                compatibilidades_df.loc[j, compatibilidades_df.columns.values[i]] = 'x'
+    restricciones_df = restricciones_df.fillna(0)
 
+    return compatibilidades_df, restricciones_df
 
-
-#cambio de los valores Nan por 0
-compatibilidades_df = compatibilidades_df.fillna(0).infer_objects(copy=False)
-print(compatibilidades_df)
-
-restricciones_df = restricciones_df.fillna(0)
-
-
- 
+def creaccion_acciones(restricciones_df):
 #creacion de load patterns
 
-for i in restricciones_df.loc[:, "Definición de 'Load Cases'"]:
-    ret = SapModel.LoadPatterns.Add(i, 3) #el numero indica el tipo de carga: 1 dead, 3 live ..
-
-
-#Se almacena en esta variable un diccionario indicando los estado en los que se puede encontrar la carga
+    for i in restricciones_df.loc[:, "Definición de 'Load Cases'"]:
+      ret = SapModel.LoadPatterns.Add(i, 3) #el numero indica el tipo de carga: 1 dead, 3 live ..
 
-valores_por_patron = {}
-for index, row in restricciones_df.iterrows():
-    patron = restricciones_df.loc[:,restricciones_df.columns[0]]
-
-    valores = [0, 1]
-
-    if row["Bidireccional?"]:
-        valores.append(-1)
-    
-    valores_por_patron[patron[index]] = list(set(valores))
-
-
-#creacion del array donde se almancenan los nombres de las cargas
-patrones = list(valores_por_patron.keys())
-
-
-
-#se hace con itertools todas las combinaciones de carga posibles sin ninguna restriccion
-todas_combinaciones = list(itertools.product(*[valores_por_patron[pat] for pat in patrones]))
 
 
 #funcion para comprobar que la combiacion de cargas es posible debido a las restricciones
@@ -423,493 +331,462 @@ def validar_combinacion(comb, patrones, compatibilidad_df, restricciones_df):
     return True
 
 
-#comprobacion de la validez de las combinaciones
-combinaciones_validas = []
-for comb in todas_combinaciones:
-    if validar_combinacion(comb, patrones, compatibilidades_df, restricciones_df):
-        combinaciones_validas.append(comb)
-
-
-#funcion para hacer la suma en valor absoluto de un array
-def suma_abs(lista):
-
-    for _ in range(len(lista)): total += abs(lista[_])
-
-    return total
-
-num_permanentes = 0
+#funcion principal para crear y validar las combinaciones de cargas
 
-#se obtiene el numero de cargas que son permanentes
-for iter, per in enumerate(restricciones_df.loc[:,"Permanentes"]):
-    if per == 'x' : num_permanentes += 1
+def crear_validar_combinaciones(restricciones_df, compatibilidades_df):
+    #Se almacena en esta variable un diccionario indicando los estado en los que se puede encontrar la carga
 
+    valores_por_patron = {}
+    for index, row in restricciones_df.iterrows():
+        patron = restricciones_df.loc[:,restricciones_df.columns[0]]
 
+        valores = [0, 1]
 
-def CrearCombo(nombre, numero, combo, coef):
+        if row["Bidireccional?"]:
+            valores.append(-1)
 
-    global SapModel
-    global patrones
+        valores_por_patron[patron[index]] = list(set(valores))
 
-    nombre_combo = nombre + "{:04}".format(numero)
 
-    ret = SapModel.RespCombo.Add(nombre_combo, 0)
-
-    for idx, patron in enumerate(patrones):
-        coeficiente = combo[idx]
-        if coeficiente != 0:
-            ret = SapModel.RespCombo.SetCaseList(nombre_combo, 0, patron, coeficiente*coef[idx])
+    #creacion del array donde se almancenan los nombres de las cargas
+    patrones = list(valores_por_patron.keys())
 
+    #se hace con itertools todas las combinaciones de carga posibles sin ninguna restriccion
+    todas_combinaciones = list(itertools.product(*[valores_por_patron[pat] for pat in patrones]))
 
+    #comprobacion de la validez de las combinaciones
+    combinaciones_validas = []
+    for comb in todas_combinaciones:
+        if validar_combinacion(comb, patrones, compatibilidades_df, restricciones_df):
+            combinaciones_validas.append(comb)
+    
+    return combinaciones_validas, patrones
 
-combos_ELUP = []
-combos_ELUA = []
-combos_ELUS = []
-combos_ELSC = []
-combos_ELSF = []
-combos_ELSCP = []
-minorados_ELUP = []
-minorados_ELSC = []
-minorados_ELSF = []
-minorados_ELSCP = []
-minorados_ELUA = []
-minorados_ELUS = []
 
+def limpiar_combos(combos, mascara, coef_comp):
+    combos_limpios = []
+    for combo in combos:
+        peligro = 0 
+        combo_masc = np.multiply(combo, mascara)
+        for i, _ in enumerate(combo_masc):
+            if combo_masc[i] == coef_comp:
+                peligro += 1
+        if peligro < 2:
+            combos_limpios.append(combo)
+    return np.array(combos_limpios)
 
-for combo in combinaciones_validas:
 
-    coeficientes_ELUP = np.zeros(len(patrones))
-    coeficientes_ELUA = np.zeros(len(patrones))
-    coeficientes_ELUS = np.zeros(len(patrones))
-    coeficientes_ELSC = np.zeros(len(patrones))
-    coeficientes_ELSF = np.zeros(len(patrones))
-    coeficientes_ELSCP = np.zeros(len(patrones))
-    n_var = 0
-    n_acc = 0
+def generar_combinaciones_norma_IAPF(combinaciones_validas, restricciones_df, norma_proyecto, vias_cargadas, patrones):
+    combos_ELUP = []
+    combos_ELUA = []
+    combos_ELUS = []
+    combos_ELSC = []
+    combos_ELSF = []
+    combos_ELSCP = []
+    minorados_ELUP = []
+    minorados_ELSC = []
+    minorados_ELSF = []
+    minorados_ELSCP = []
+    minorados_ELUA = []
+    minorados_ELUS = []
+
+
+    for combo in combinaciones_validas:
+
+        coeficientes_ELUP = np.zeros(len(patrones))
+        coeficientes_ELUA = np.zeros(len(patrones))
+        coeficientes_ELUS = np.zeros(len(patrones))
+        coeficientes_ELSC = np.zeros(len(patrones))
+        coeficientes_ELSF = np.zeros(len(patrones))
+        coeficientes_ELSCP = np.zeros(len(patrones))
+        n_var = 0
+        n_acc = 0
 
-    for i in range(len(combo)):
+        for i in range(len(combo)):
 
 
-        if norma_proyecto == "IAPF":
-            #primero se comprueba si la carga es permanente o no
-            if restricciones_df.loc[i,"Permanentes"]:
-                #luego constante o no
-                if restricciones_df.loc[i,"Tipo"] == "Constante":
+            if norma_proyecto == "IAPF":
+                #primero se comprueba si la carga es permanente o no
+                if restricciones_df.loc[i,"Permanentes"]:
+                    #luego constante o no
+                    if restricciones_df.loc[i,"Tipo"] == "Constante":
+                        if restricciones_df.loc[i,"Direccion"] == "Desfavorable":
+                            #ELU
+                            coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Persistente"]["Cte"]
+                            coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Cte"]
+                            coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Cte"]
+                            #ELS
+                            coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Cte"]
+                            coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Cte"]
+                            coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Cte"]
+                        elif restricciones_df.loc[i,"Direccion"] == "Favorable":
+                            #ELU
+                            coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Favorable"]["Persistente"]["Cte"]
+                            coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Cte"]
+                            coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Cte"]
+                            #ELS
+                            coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Cte"]
+                            coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Cte"]
+                            coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Cte"]
+                    elif restricciones_df.loc[i,"Tipo"] == "No Constante":
+                        if restricciones_df.loc[i,"Direccion"] == "Desfavorable":
+                            #ELU
+                            coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Persistente"]["NoCte"]
+                            coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["NoCte"]
+                            coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["NoCte"]
+                            #ELS
+                            coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["NoCte"]
+                            coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["NoCte"]
+                            coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["NoCte"]
+                        elif restricciones_df.loc[i,"Direccion"] == "Favorable":
+                            coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Favorable"]["Persistente"]["NoCte"]
+                            coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["NoCte"]
+                            coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["NoCte"]
+                            #ELS
+                            coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["NoCte"]
+                            coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["NoCte"]
+                            coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["NoCte"]
+                elif restricciones_df.loc[i,"Tipo"] == "Accidental":
+                    if combo[i] != 0: n_acc += 1
                     if restricciones_df.loc[i,"Direccion"] == "Desfavorable":
                         #ELU
-                        coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Persistente"]["Cte"]
-                        coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Cte"]
-                        coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Cte"]
+                        coeficientes_ELUP[i] = 0
+                        coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Accidental"]
+                        coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Accidental"]
                         #ELS
-                        coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Cte"]
-                        coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Cte"]
-                        coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Cte"]
+                        coeficientes_ELSC[i] =  0
+                        coeficientes_ELSF[i] =  0
+                        coeficientes_ELSCP[i] = 0
                     elif restricciones_df.loc[i,"Direccion"] == "Favorable":
                         #ELU
-                        coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Favorable"]["Persistente"]["Cte"]
-                        coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Cte"]
-                        coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Cte"]
+                        coeficientes_ELUP[i] = 0
+                        coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Accidental"]
+                        coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Accidental"]
                         #ELS
-                        coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Cte"]
-                        coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Cte"]
-                        coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Cte"]
-                elif restricciones_df.loc[i,"Tipo"] == "No Constante":
+                        coeficientes_ELSC[i] =  0
+                        coeficientes_ELSF[i] =  0
+                        coeficientes_ELSCP[i] = 0
+                elif restricciones_df.loc[i,"Tipo"] == "Variable":
+                    if combo[i] != 0: n_var += 1
                     if restricciones_df.loc[i,"Direccion"] == "Desfavorable":
                         #ELU
-                        coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Persistente"]["NoCte"]
-                        coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["NoCte"]
-                        coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["NoCte"]
+                        coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Persistente"]["Variable"]
+                        coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Variable"]
+                        coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Variable"]
                         #ELS
-                        coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["NoCte"]
-                        coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["NoCte"]
-                        coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["NoCte"]
+                        coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Variable"]
+                        coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Variable"]
+                        coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Variable"]
                     elif restricciones_df.loc[i,"Direccion"] == "Favorable":
-                        coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Favorable"]["Persistente"]["NoCte"]
-                        coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["NoCte"]
-                        coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["NoCte"]
+                        #ELU
+                        coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Favorable"]["Persistente"]["Variable"]
+                        coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Variable"]
+                        coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Variable"]
                         #ELS
-                        coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["NoCte"]
-                        coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["NoCte"]
-                        coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["NoCte"]
-            elif restricciones_df.loc[i,"Tipo"] == "Accidental":
-                if combo[i] != 0: n_acc += 1
-                if restricciones_df.loc[i,"Direccion"] == "Desfavorable":
-                    #ELU
-                    coeficientes_ELUP[i] = 0
-                    coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Accidental"]
-                    coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Accidental"]
-                    #ELS
-                    coeficientes_ELSC[i] =  0
-                    coeficientes_ELSF[i] =  0
-                    coeficientes_ELSCP[i] = 0
-                elif restricciones_df.loc[i,"Direccion"] == "Favorable":
-                    #ELU
-                    coeficientes_ELUP[i] = 0
-                    coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Accidental"]
-                    coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Accidental"]
-                    #ELS
-                    coeficientes_ELSC[i] =  0
-                    coeficientes_ELSF[i] =  0
-                    coeficientes_ELSCP[i] = 0
-            elif restricciones_df.loc[i,"Tipo"] == "Variable":
-                if combo[i] != 0: n_var += 1
-                if restricciones_df.loc[i,"Direccion"] == "Desfavorable":
-                    #ELU
-                    coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Persistente"]["Variable"]
-                    coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Variable"]
-                    coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Desfavorable"]["Accidental"]["Variable"]
-                    #ELS
-                    coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Variable"]
-                    coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Variable"]
-                    coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Desfavorable"]["Persistente"]["Variable"]
-                elif restricciones_df.loc[i,"Direccion"] == "Favorable":
-                    #ELU
-                    coeficientes_ELUP[i] = normas["IAPF"]["ELU"]["Favorable"]["Persistente"]["Variable"]
-                    coeficientes_ELUA[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Variable"]
-                    coeficientes_ELUS[i] = normas["IAPF"]["ELU"]["Favorable"]["Accidental"]["Variable"]
-                    #ELS
-                    coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Variable"]
-                    coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Variable"]
-                    coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Variable"]
-        elif norma_proyecto == "IAP":
-            pass    
-        
-        
-    minorados_ELUP.clear()
-    minorados_ELUA.clear()
-    minorados_ELUS.clear()
-    minorados_ELSC.clear()
-    minorados_ELSF.clear()
-    minorados_ELSCP.clear()
-
+                        coeficientes_ELSC[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Variable"]
+                        coeficientes_ELSF[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Variable"]
+                        coeficientes_ELSCP[i] = normas["IAPF"]["ELS"]["Favorable"]["Persistente"]["Variable"]
+            elif norma_proyecto == "IAP":
+                pass    
+            
+            
+        minorados_ELUP.clear()
+        minorados_ELUA.clear()
+        minorados_ELUS.clear()
+        minorados_ELSC.clear()
+        minorados_ELSF.clear()
+        minorados_ELSCP.clear()
+
+
+        if n_acc:
+            coef_var_ELUS = np.ones(len(patrones))
+            coef_var_ELUA = np.ones(len(patrones))
+            for i in range(len(combo)):
+                if (restricciones_df.loc[i,"Accion IAPF"] == "Sismo") and combo[i] != 0:
+                    for j in range(len(combo)):
+                        if (restricciones_df.loc[j,"Tipo"] == "Variable") and j:
+                            if restricciones_df.loc[j,"Accion IAPF"] == "Trafico":
+                                coef_var_ELUS[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
+                            if restricciones_df.loc[j,"Accion IAPF"] == "Resto":
+                                coef_var_ELUS[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
+                    minorados_ELUS.append(coef_var_ELUS)
+                if (restricciones_df.loc[i,"Accion IAPF"] != "Sismo") and (restricciones_df.loc[i,"Tipo"] == "Accidental") and combo[i] != 0:
+                    appended_for_acc = False
+                    for k in range(len(combo)):
+                        coef_var_ELUA = np.ones(len(patrones))
+                        if (restricciones_df.loc[k,"Tipo"] == "Variable") and combo[k] != 0:
+                            if restricciones_df.loc[k,"Accion IAPF"] == "Trafico":
+                                coef_var_ELUA[k] = normas["IAPF"]["CoefVar"]["Trafico"]["psi1"][vias_cargadas if int(vias_cargadas) < 4 else "3"]
+                            else:
+                                coef_var_ELUA[k] = normas["IAPF"]["CoefVar"]["Resto"]["psi1"]
+                            for j in range(len(combo)):
+                                if (restricciones_df.loc[j,"Tipo"] == "Variable") and (j != k):
+                                    #se asigna el coeficiente de la variable al resto de variables
+                                    if restricciones_df.loc[j,"Accion IAPF"] == "Trafico":
+                                        coef_var_ELUA[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
+                                    else:
+                                        coef_var_ELUA[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
+                            minorados_ELUA.append(coef_var_ELUA)
+                            appended_for_acc = True
+                    # Si no se encontraron variables activas, añadimos el vector por defecto (unos)
+                    if not appended_for_acc:
+                        minorados_ELUA.append(np.ones(len(patrones)))
 
-    if n_acc:
-        coef_var_ELUS = np.ones(len(patrones))
-        coef_var_ELUA = np.ones(len(patrones))
-        for i in range(len(combo)):
-            if (restricciones_df.loc[i,"Accion IAPF"] == "Sismo") and combo[i] != 0:
-                for j in range(len(combo)):
-                    if (restricciones_df.loc[j,"Tipo"] == "Variable") and j:
-                        if restricciones_df.loc[j,"Accion IAPF"] == "Trafico":
-                            coef_var_ELUS[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
-                        if restricciones_df.loc[j,"Accion IAPF"] == "Resto":
-                            coef_var_ELUS[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
-                minorados_ELUS.append(coef_var_ELUS)
-            if (restricciones_df.loc[i,"Accion IAPF"] != "Sismo") and (restricciones_df.loc[i,"Tipo"] == "Accidental") and combo[i] != 0:
-                appended_for_acc = False
-                for k in range(len(combo)):
-                    coef_var_ELUA = np.ones(len(patrones))
-                    if (restricciones_df.loc[k,"Tipo"] == "Variable") and combo[k] != 0:
-                        if restricciones_df.loc[k,"Accion IAPF"] == "Trafico":
-                            coef_var_ELUA[k] = normas["IAPF"]["CoefVar"]["Trafico"]["psi1"][vias_cargadas if int(vias_cargadas) < 4 else "3"]
+        else:
+            if n_var == 1:
+                coef_var_ELSF = np.ones(len(patrones))
+                coef_var_ELSCP = np.ones(len(patrones))
+                for i in range(len(combo)):
+                    if (restricciones_df.loc[i,"Tipo"] == "Variable") and combo[i] != 0:
+                        if restricciones_df.loc[i,"Accion IAPF"] == "Trafico":
+                            coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi1"][vias_cargadas if int(vias_cargadas) < 4 else "3"]
+                            coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
                         else:
-                            coef_var_ELUA[k] = normas["IAPF"]["CoefVar"]["Resto"]["psi1"]
+                            coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi1"]
+                            coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
+
+
+            while n_var > 1:
+                n_var -= 1 
+                #se busca la primera variable en el combo y se asigna el coeficiente
+                for i in range(len(combo)):
+                    coef_var_ELUP = np.ones(len(patrones))
+                    coef_var_ELSC = np.ones(len(patrones))
+                    coef_var_ELSF = np.ones(len(patrones))
+                    coef_var_ELSCP =np.ones(len(patrones))
+                    if (restricciones_df.loc[i,"Tipo"] == "Variable") and combo[i] != 0:
+                        if restricciones_df.loc[i,"Accion IAPF"] == "Trafico":
+                            coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi1"][vias_cargadas if int(vias_cargadas) < 4 else "3"]
+                            coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
+                        else:
+                            coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi1"]
+                            coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
                         for j in range(len(combo)):
-                            if (restricciones_df.loc[j,"Tipo"] == "Variable") and (j != k):
-                                #se asigna el coeficiente de la variable al resto de variables
+                            if (restricciones_df.loc[j,"Tipo"] == "Variable") and (j != i):
+                                    #se asigna el coeficiente de la variable al resto de variables
                                 if restricciones_df.loc[j,"Accion IAPF"] == "Trafico":
-                                    coef_var_ELUA[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
+                                    coef_var_ELUP[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi0"]
+                                    coef_var_ELSC[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi0"]
+                                    coef_var_ELSF[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
+                                    coef_var_ELSCP[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
                                 else:
-                                    coef_var_ELUA[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
-                        minorados_ELUA.append(coef_var_ELUA)
-                        appended_for_acc = True
-                # Si no se encontraron variables activas, añadimos el vector por defecto (unos)
-                if not appended_for_acc:
-                    minorados_ELUA.append(np.ones(len(patrones)))
-
-    else:
-        if n_var == 1:
-            coef_var_ELSF = np.ones(len(patrones))
-            coef_var_ELSCP = np.ones(len(patrones))
-            for i in range(len(combo)):
-                if (restricciones_df.loc[i,"Tipo"] == "Variable") and combo[i] != 0:
-                    if restricciones_df.loc[i,"Accion IAPF"] == "Trafico":
-                        coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi1"][vias_cargadas if int(vias_cargadas) < 4 else "3"]
-                        coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
-                    else:
-                        coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi1"]
-                        coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
-
-
-        while n_var > 1:
-            n_var -= 1 
-            #se busca la primera variable en el combo y se asigna el coeficiente
-            for i in range(len(combo)):
-                coef_var_ELUP = np.ones(len(patrones))
-                coef_var_ELSC = np.ones(len(patrones))
-                coef_var_ELSF = np.ones(len(patrones))
-                coef_var_ELSCP =np.ones(len(patrones))
-                if (restricciones_df.loc[i,"Tipo"] == "Variable") and combo[i] != 0:
-                    if restricciones_df.loc[i,"Accion IAPF"] == "Trafico":
-                        coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi1"][vias_cargadas if int(vias_cargadas) < 4 else "3"]
-                        coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
-                    else:
-                        coef_var_ELSF[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi1"]
-                        coef_var_ELSCP[i] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
-                    for j in range(len(combo)):
-                        if (restricciones_df.loc[j,"Tipo"] == "Variable") and (j != i):
-                                #se asigna el coeficiente de la variable al resto de variables
-                            if restricciones_df.loc[j,"Accion IAPF"] == "Trafico":
-                                coef_var_ELUP[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi0"]
-                                coef_var_ELSC[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi0"]
-                                coef_var_ELSF[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
-                                coef_var_ELSCP[j] = normas["IAPF"]["CoefVar"]["Trafico"]["psi2"]
-                            else:
-                                coef_var_ELUP[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi0"]
-                                coef_var_ELSC[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi0"]
-                                coef_var_ELSF[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
-                                coef_var_ELSCP[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
-                    minorados_ELUP.append(coef_var_ELUP)
-                    minorados_ELSC.append(coef_var_ELSC)
-                    minorados_ELSF.append(coef_var_ELSF)
-                    minorados_ELSCP.append(coef_var_ELSCP)
+                                    coef_var_ELUP[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi0"]
+                                    coef_var_ELSC[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi0"]
+                                    coef_var_ELSF[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
+                                    coef_var_ELSCP[j] = normas["IAPF"]["CoefVar"]["Resto"]["psi2"]
+                        minorados_ELUP.append(coef_var_ELUP)
+                        minorados_ELSC.append(coef_var_ELSC)
+                        minorados_ELSF.append(coef_var_ELSF)
+                        minorados_ELSCP.append(coef_var_ELSCP)
+
+
+        if minorados_ELUP:
+            for minorado in minorados_ELUP: 
+                combos_ELUP.append(np.multiply(np.multiply(coeficientes_ELUP, combo),minorado))
+            for minorado in minorados_ELSC: 
+                combos_ELSC.append(np.multiply(np.multiply(coeficientes_ELSC, combo),minorado))
+            for minorado in minorados_ELSF: 
+                combos_ELSF.append(np.multiply(np.multiply(coeficientes_ELSF, combo),minorado))
+            for minorado in minorados_ELSCP: 
+                combos_ELSCP.append(np.multiply(np.multiply(coeficientes_ELSCP, combo),minorado))
+        else:
+            combos_ELUP.append(np.multiply(coeficientes_ELUP, combo))
+            combos_ELSC.append(np.multiply(coeficientes_ELSC, combo))
+            combos_ELSF.append(np.multiply(coeficientes_ELSF, combo))if not n_var else combos_ELSF.append(np.multiply(np.multiply(coeficientes_ELSF, combo),coef_var_ELSF))
+            combos_ELSCP.append(np.multiply(coeficientes_ELSCP, combo)) if not n_var else combos_ELSCP.append(np.multiply(np.multiply(coeficientes_ELSCP, combo),coef_var_ELSCP))
+        if minorados_ELUS:
+            for minorado in minorados_ELUS:
+                combos_ELUS.append(np.multiply(np.multiply(coeficientes_ELUS, combo),minorado))
+        if minorados_ELUA:
+            for minorado in minorados_ELUA:
+                combos_ELUA.append(np.multiply(np.multiply(coeficientes_ELUA, combo),minorado))
+
+
+
+    combos_ELUP = np.unique(np.array(combos_ELUP), axis=0)
+    combos_ELUA =  np.unique(np.array(combos_ELUA), axis=0)
+    combos_ELUS =  np.unique(np.array(combos_ELUS), axis=0)
+    combos_ELSC =  np.unique(np.array(combos_ELSC), axis=0)
+    combos_ELSF =  np.unique(np.array(combos_ELSF), axis=0)
+    combos_ELSCP =  np.unique(np.array(combos_ELSCP), axis=0)
+
+
+    restricciones_array = restricciones_df.loc[:,"Tipo"]
+
+    mascara = np.multiply(np.ones(len(restricciones_array)), (restricciones_array == "Variable").astype(int))
+
+
+    combos_ELUP = limpiar_combos(combos_ELUP, mascara, 1.5)
+    combos_ELSC = limpiar_combos(combos_ELSC, mascara, 1)
+    combos_ELSF = limpiar_combos(combos_ELSF, mascara, 1)
+    combos_ELSCP = limpiar_combos(combos_ELSCP, mascara, 1)
+
+    return combos_ELUP, combos_ELUA, combos_ELUS, combos_ELSC, combos_ELSF, combos_ELSCP
+
+
+def agregar_combinaciones_carga(combos_data, nombre_tipo, total_combos, patrones, acum):
+    combo_num = 0
+    for combo in combos_data:
+        combo_name = f"{nombre_tipo}_{combo_num:03d}"
+        ret = SapModel.RespCombo.Add(combo_name, 0)
+        for idx, patron in enumerate(patrones):
+            coeficiente = combo[idx]
+            if coeficiente != 0:
+                ret = SapModel.RespCombo.SetCaseList(combo_name, 0, patron, coeficiente)
+        printProgressBar(combo_num + acum, total_combos, prefix = f'Creando combos {nombre_tipo}:', suffix = 'Completado', length = 50)
+        combo_num += 1
+    return combo_num  
+
+
+def crear_combo_envolvente(combo_name = "", busca = "", total_envolventes = 0, acumulador = 0):
+    contador_envolvente = 0
+    comboNames = SapModel.RespCombo.GetNameList()
+    patron = []
+    for j in range(comboNames[0]):
+        if busca in comboNames[1][j]: patron.append(comboNames[1][j])  
+    if len(patron):
+        ret = SapModel.RespCombo.Add(combo_name, 1)
+        for i, name in enumerate(patron):
+            ret = SapModel.RespCombo.SetCaseList(combo_name, 1, name, 1)
+            contador_envolvente += 1
+            printProgressBar(contador_envolvente + acumulador, total_envolventes, prefix = f'Creando {combo_name} envolvente:', suffix = 'Completado', length = 50)
+    return len(patron)
+
+
+def main(ruta_excel, norma_proyecto, vias_cargadas):
+    compatibilidades_df, restricciones_df =extraer_datos_excel(ruta_excel)
+    creaccion_acciones(restricciones_df)
+    combinaciones_validas, patrones = crear_validar_combinaciones(restricciones_df, compatibilidades_df)
+    combos_ELUP, combos_ELUA, combos_ELUS, combos_ELSC, combos_ELSF, combos_ELSCP = \
+        generar_combinaciones_norma_IAPF(combinaciones_validas, restricciones_df, norma_proyecto, vias_cargadas, patrones)
+    tot_combos = len(combos_ELUP) + len(combos_ELSC) + len(combos_ELSF) + len(combos_ELSCP) + len(combos_ELUA) + len(combos_ELUS)
+    acum_c = agregar_combinaciones_carga(combos_ELUP, "ELU_P", tot_combos, patrones, 0)
+    acum_c += agregar_combinaciones_carga(combos_ELUA, "ELU_ACC", tot_combos, patrones, acum_c)
+    acum_c += agregar_combinaciones_carga(combos_ELUS, "ELU_SIS", tot_combos, patrones, acum_c)
+    acum_c += agregar_combinaciones_carga(combos_ELSC, "ELS_C_", tot_combos, patrones, acum_c)
+    acum_c += agregar_combinaciones_carga(combos_ELSF, "ELS_F_", tot_combos, patrones, acum_c)
+    _ = agregar_combinaciones_carga(combos_ELSCP, "ELS_CP", tot_combos, patrones, acum_c)
+    print("")
+    total_envolventes = 0
+    temp_comboNames = SapModel.RespCombo.GetNameList()
+    for combo_type in ["ELU_P", "ELU_ACC", "ELU_SIS", "ELS_C_", "ELS_F_", "ELS_CP"]:
+        total_envolventes += sum(1 for idx in range(temp_comboNames[0]) if combo_type in temp_comboNames[1][idx])
+    acum = crear_combo_envolvente("1. ENV ELU P", "ELU_P", total_envolventes, 0)
+    acum += crear_combo_envolvente("2. ENV ELU ACC", "ELU_ACC", total_envolventes, acum)
+    acum += crear_combo_envolvente("3. ENV ELU SIS", "ELU_SIS", total_envolventes, acum)
+    acum += crear_combo_envolvente("4. ENV ELS C", "ELS_C_", total_envolventes, acum)
+    acum += crear_combo_envolvente("5. ENV ELS F", "ELS_F_", total_envolventes, acum)
+    _ = crear_combo_envolvente("6. ENV ELS CP", "ELS_CP", total_envolventes, acum)
+    
+
+def crear_ventana_configuracion():
+    """Crea una ventana gráfica para configuración inicial"""
+    ventana = tk.Tk()
+    ventana.title("Configuración de Combinaciones")
+    ventana.geometry("600x600")
+    ventana.attributes('-topmost', True)
+    script_dir = os.path.dirname(os.path.abspath(__file__))
+    icon_path = os.path.join(script_dir, 'AYRE.ico')
+    ventana.iconbitmap(icon_path)
+
+    
+    # Título
+    titulo = tk.Label(ventana, text="Configuración Inicial", font=("Arial", 14, "bold"))
+    titulo.pack(pady=10)
+    
+    # Checkbox 1: Borrar combinaciones
+    var_combos = tk.BooleanVar(value=True)
+    check_combos = tk.Checkbutton(ventana, text="Borrar combinaciones existentes", variable=var_combos, font=("Arial", 10))
+    check_combos.pack(anchor=tk.W, padx=20, pady=5)
+    
+    # Checkbox 2: Borrar cargas
+    var_cargas = tk.BooleanVar(value=True)
+    check_cargas = tk.Checkbutton(ventana, text="Borrar cargas existentes", variable=var_cargas, font=("Arial", 10))
+    check_cargas.pack(anchor=tk.W, padx=20, pady=5)
+
+    # Botón Borrar Todo
+    def on_borrar_todo():
+        if var_combos.get():
+            borrar_combos_existentes()
+        if var_cargas.get():
+            borrar_load_cases()
+            borrar_patrones_carga()
+        
+    boton_borrar = tk.Button(ventana, text="Borrar Selección", command=on_borrar_todo, font=("Arial", 11), bg="#f44336", fg="white", padx=10, pady=5)
+    boton_borrar.pack()
+    
+    # Frame para norma
+    frame_norma = tk.Frame(ventana)
+    frame_norma.pack(anchor=tk.W, padx=20, pady=10)
+    label_norma = tk.Label(frame_norma, text="Norma:", font=("Arial", 10))
+    label_norma.pack(side=tk.LEFT, padx=5)
+    var_norma = tk.StringVar(value="IAPF")
+    combo_norma = tk.ttk.Combobox(frame_norma, textvariable=var_norma, values=["IAPF", "IAP"], state="readonly", width=15)
+    combo_norma.pack(side=tk.LEFT, padx=5)
+    
+    # Frame para vías
+    frame_vias = tk.Frame(ventana)
+    frame_vias.pack(anchor=tk.W, padx=20, pady=10)
+    label_vias = tk.Label(frame_vias, text="Vías cargadas:", font=("Arial", 10))
+    label_vias.pack(side=tk.LEFT, padx=5)
+    var_vias = tk.StringVar(value="1")
+    combo_vias = tk.ttk.Combobox(frame_vias, textvariable=var_vias, values=["1", "2", "3", "Más de 3"], state="readonly", width=15)
+    combo_vias.pack(side=tk.LEFT, padx=5)
 
+    # Frame para selección de archivo Excel
+    frame_excel = tk.Frame(ventana)
+    frame_excel.pack(anchor=tk.W, padx=20, pady=10)
+    label_excel = tk.Label(frame_excel, text="Archivo Excel:", font=("Arial", 10))
+    label_excel.pack(side=tk.LEFT, padx=5)
+    var_excel = tk.StringVar()
+    entry_excel = tk.Entry(frame_excel, textvariable=var_excel, width=40)
+    entry_excel.pack(side=tk.LEFT, padx=5)
+    
+    def browse_excel():
+        ruta = askopenfilename(filetypes=[("Excel files", "*.xlsx *.xls")])
+        if ruta:
+            var_excel.set(ruta)
+        boton_ok.config(state=tk.NORMAL)
     
-    if minorados_ELUP:
-        for minorado in minorados_ELUP: 
-            combos_ELUP.append(np.multiply(np.multiply(coeficientes_ELUP, combo),minorado))
-        for minorado in minorados_ELSC: 
-            combos_ELSC.append(np.multiply(np.multiply(coeficientes_ELSC, combo),minorado))
-        for minorado in minorados_ELSF: 
-            combos_ELSF.append(np.multiply(np.multiply(coeficientes_ELSF, combo),minorado))
-        for minorado in minorados_ELSCP: 
-            combos_ELSCP.append(np.multiply(np.multiply(coeficientes_ELSCP, combo),minorado))
-    else:
-        combos_ELUP.append(np.multiply(coeficientes_ELUP, combo))
-        combos_ELSC.append(np.multiply(coeficientes_ELSC, combo))
-        combos_ELSF.append(np.multiply(coeficientes_ELSF, combo))if not n_var else combos_ELSF.append(np.multiply(np.multiply(coeficientes_ELSF, combo),coef_var_ELSF))
-        combos_ELSCP.append(np.multiply(coeficientes_ELSCP, combo)) if not n_var else combos_ELSCP.append(np.multiply(np.multiply(coeficientes_ELSCP, combo),coef_var_ELSCP))
-    if minorados_ELUS:
-        for minorado in minorados_ELUS:
-            combos_ELUS.append(np.multiply(np.multiply(coeficientes_ELUS, combo),minorado))
-    if minorados_ELUA:
-        for minorado in minorados_ELUA:
-            combos_ELUA.append(np.multiply(np.multiply(coeficientes_ELUA, combo),minorado))
+    boton_browse = tk.Button(frame_excel, text="Seleccionar", command=browse_excel, font=("Arial", 10))
+    boton_browse.pack(side=tk.LEFT, padx=5)
     
+    # Botón OK
+    def on_ok():
+        main(var_excel.get(), var_norma.get(), var_vias.get())
+        
+    
+    boton_ok = tk.Button(ventana, text="Crear combos", command=on_ok, font=("Arial", 11), bg="#4CAF50", fg="white", padx=10, pady=5)
+    boton_ok.pack(pady=20)
+    boton_ok.config(state=tk.DISABLED)
 
+    # Boton extraer datos
+    def on_extraer():
+        extraer_combinaciones_a_excel(SapModel, var_excel.get())
 
-combos_ELUP = np.unique(np.array(combos_ELUP), axis=0)
-combos_ELUA =  np.unique(np.array(combos_ELUA), axis=0)
-combos_ELUS =  np.unique(np.array(combos_ELUS), axis=0)
-combos_ELSC =  np.unique(np.array(combos_ELSC), axis=0)
-combos_ELSF =  np.unique(np.array(combos_ELSF), axis=0)
-combos_ELSCP =  np.unique(np.array(combos_ELSCP), axis=0)
+    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)
 
+    def comprobacion_SAP_cerrado():
+        try:    
+            ret = SapModel.Analyze.GetCaseStatus()
+            if ret[0] > 0:
+                estados = ret[2]
+                if any(estado == 4 for estado in estados):
+                    boton_extraer.config(state=tk.NORMAL)
+                else: 
+                    boton_extraer.config(state=tk.DISABLED)
+        except (comtypes.COMError, Exception) as e:
+            sys.exit(0)  # Cierra la aplicación si SAP2000 está cerrado
 
-restricciones_array = restricciones_df.loc[:,"Tipo"]
+        ventana.after(1000, comprobacion_SAP_cerrado)  # Verifica cada segundo
 
-mascara = np.multiply(np.ones(len(restricciones_array)), (restricciones_array == "Variable").astype(int))
+    comprobacion_SAP_cerrado()
 
+    ventana.mainloop()
 
-def limpiar_combos(combos, mascara, coef_comp):
-    combos_limpios = []
-    for combo in combos:
-        peligro = 0 
-        combo_masc = np.multiply(combo, mascara)
-        for i, _ in enumerate(combo_masc):
-            if combo_masc[i] == coef_comp:
-                peligro += 1
-        if peligro < 2:
-            combos_limpios.append(combo)
-    return np.array(combos_limpios)
 
 
+# Mostrar ventana de configuración
+config = crear_ventana_configuracion()
 
-combos_ELUP = limpiar_combos(combos_ELUP, mascara, 1.5)
-combos_ELSC = limpiar_combos(combos_ELSC, mascara, 1)
-combos_ELSF = limpiar_combos(combos_ELSF, mascara, 1)
-combos_ELSCP = limpiar_combos(combos_ELSCP, mascara, 1)
-
-
-
-#print("------------------------------------------------")
-#print(combos_ELUP)
-#print(len(combos_ELUP), "ELU Persistente" )
-#print("------------------------------------------------")
-#print(combos_ELUA)
-#print(len(combos_ELUA), "ELU Accidental")
-#print("------------------------------------------------")
-#print(combos_ELUS)
-#print(len(combos_ELUS), "ELU Sismo")
-#print("------------------------------------------------")
-#print(combos_ELSC)
-#print(len(combos_ELSC), "ELS Caracteristico")
-#print("------------------------------------------------")
-#print(combos_ELSF)
-#print(len(combos_ELSF), "ELS Frecuente")
-#print("------------------------------------------------")
-#print(combos_ELSCP)
-#print(len(combos_ELSCP), "ELS Cuasipermanente")
-#print()
-
-total_combos = len(combos_ELUP) + len(combos_ELSC) + len(combos_ELSF) + len(combos_ELSCP) + len(combos_ELUA) + len(combos_ELUS)
-#creacion de los combos en SAP2000
-
-#creacion de los combos ELU Permantentes
-
-combo_num = 0 
-
-for combo in combos_ELUP:
-    combo_name = "ELU_P_{:03d}".format(combo_num)
-    ret = SapModel.RespCombo.Add(combo_name, 0)
-    for idx, patron in enumerate(patrones):
-        coeficiente = combo[idx]
-        if coeficiente != 0:
-            ret = SapModel.RespCombo.SetCaseList(combo_name, 0, patron, coeficiente)
-    printProgressBar(combo_num, total_combos, prefix = 'Creando combos ELU Persistente:', suffix = 'Completado', length = 50)
-    combo_num += 1
-
-#creacion de los combos ELU Accidentales
-tot = combo_num
-combo_num = 0
-
-for combo in combos_ELUA:
-    combo_name = "ELU_ACC_{:03d}".format(combo_num)
-    ret = SapModel.RespCombo.Add(combo_name, 0)
-    for idx, patron in enumerate(patrones):
-        coeficiente = combo[idx]
-        if coeficiente != 0:
-            ret = SapModel.RespCombo.SetCaseList(combo_name, 0, patron, coeficiente)
-    printProgressBar(tot + combo_num, total_combos, prefix = 'Creando combos ELU Accidental:', suffix = 'Completado', length = 50)
-    combo_num += 1
-
-#creacion de los combos ELU Sismo
-tot += combo_num
-combo_num = 0
-for combo in combos_ELUS:
-    combo_name = "ELU_SIS_{:03d}".format(combo_num)
-    ret = SapModel.RespCombo.Add(combo_name, 0)
-    for idx, patron in enumerate(patrones):
-        coeficiente = combo[idx]
-        if coeficiente != 0:
-            ret = SapModel.RespCombo.SetCaseList(combo_name, 0, patron, coeficiente)
-    printProgressBar(tot+combo_num, total_combos, prefix = 'Creando combos ELU Sismo:', suffix = 'Completado', length = 50) 
-    combo_num += 1
-
-#creacion de los combos ELS Caracteristico
-tot += combo_num
-combo_num = 0
-
-for combo in combos_ELSC:
-    combo_name = "ELS_C_{:03d}".format(combo_num)
-    ret = SapModel.RespCombo.Add(combo_name, 0)
-    for idx, patron in enumerate(patrones):
-        coeficiente = combo[idx]
-        if coeficiente != 0:
-            ret = SapModel.RespCombo.SetCaseList(combo_name, 0, patron, coeficiente)
-    printProgressBar(tot+combo_num, total_combos, prefix = 'Creando combos ELS Caracteristico:', suffix = 'Completado', length = 50) 
-    combo_num += 1
-
-#creacion de los combos ELS Frecuente
-tot += combo_num
-combo_num = 0 
-
-for combo in combos_ELSF:
-    combo_name = "ELS_F_{:03d}".format(combo_num)
-    ret = SapModel.RespCombo.Add(combo_name, 0)
-    for idx, patron in enumerate(patrones):
-        coeficiente = combo[idx]
-        if coeficiente != 0:
-            ret = SapModel.RespCombo.SetCaseList(combo_name, 0, patron, coeficiente)
-    printProgressBar(tot+combo_num, total_combos, prefix = 'Creando combos ELS Frecuente:', suffix = 'Completado', length = 50)
-    combo_num += 1
-
-#creacion de los combos ELS Cuasi Permanente
-tot += combo_num
-combo_num = 0
-
-for combo in combos_ELSCP:
-    combo_name = "ELS_CP_{:03d}".format(combo_num)
-    ret = SapModel.RespCombo.Add(combo_name, 0)
-    for idx, patron in enumerate(patrones):
-        coeficiente = combo[idx]
-        if coeficiente != 0:
-            ret = SapModel.RespCombo.SetCaseList(combo_name, 0, patron, coeficiente)
-    printProgressBar(tot+combo_num, total_combos, prefix = 'Creando combos ELS Cuasipermanente:', suffix = 'Completado', length = 50)
-    combo_num += 1
-printProgressBar(total_combos, total_combos, prefix = 'Creando combos ELS Cuasipermanente:', suffix = 'Completado', length = 50)
-print(f"{VERDE}Combos creados exitosamente{RESET}")
-
-#creacion del combo envolvente 
-print()
-
-
-combo_name = "1. ENV ELU P"
-ret = SapModel.RespCombo.Add(combo_name, 1)
-comboNames = SapModel.RespCombo.GetNameList()
-patron = []
-for j in range(comboNames[0]):
-    if "ELU_P" in comboNames[1][j]: patron.append(comboNames[1][j])  
-
-# Calcular total de combos envolventes a crear
-total_envolventes = 0
-temp_comboNames = SapModel.RespCombo.GetNameList()
-for combo_type in ["ELU_P", "ELU_ACC", "ELU_SIS", "ELS_C_", "ELS_F_", "ELS_CP"]:
-    total_envolventes += sum(1 for idx in range(temp_comboNames[0]) if combo_type in temp_comboNames[1][idx])
-
-contador_envolvente = 0
-for i, name in enumerate(patron):
-    ret = SapModel.RespCombo.SetCaseList(combo_name, 1, name, 1)
-    contador_envolvente += 1
-    printProgressBar(contador_envolvente, total_envolventes, prefix = 'Creando ELU P envolvente:', suffix = 'Completado', length = 50)
-print()
-combo_name = "2. ENV ELU ACC"
-ret = SapModel.RespCombo.Add(combo_name, 1)
-comboNames = SapModel.RespCombo.GetNameList()
-patron = []
-for j in range(comboNames[0]):
-    if "ELU_ACC" in comboNames[1][j]: patron.append(comboNames[1][j])  
-for i, name in enumerate(patron):
-    ret = SapModel.RespCombo.SetCaseList(combo_name, 1, name, 1)
-    contador_envolvente += 1
-    printProgressBar(contador_envolvente, total_envolventes, prefix = 'Creando ELU Acc envolvente:', suffix = 'Completado', length = 50)
-print()
-combo_name = "3. ENV ELU SIS"
-ret = SapModel.RespCombo.Add(combo_name, 1)
-comboNames = SapModel.RespCombo.GetNameList()
-patron = []
-for j in range(comboNames[0]):
-    if "ELU_SIS" in comboNames[1][j]: patron.append(comboNames[1][j])  
-for i, name in enumerate(patron):
-    ret = SapModel.RespCombo.SetCaseList(combo_name, 1, name, 1)
-    contador_envolvente += 1
-    printProgressBar(contador_envolvente, total_envolventes, prefix = 'Creando ELU Sis envolvente:', suffix = 'Completado', length = 50)
-print()
-combo_name = "4. ENV ELS C"
-ret = SapModel.RespCombo.Add(combo_name, 1)
-comboNames = SapModel.RespCombo.GetNameList()
-patron = []
-for j in range(comboNames[0]):
-    if "ELS_C_" in comboNames[1][j]: patron.append(comboNames[1][j])  
-for i, name in enumerate(patron):
-    ret = SapModel.RespCombo.SetCaseList(combo_name, 1, name, 1)
-    contador_envolvente += 1
-    printProgressBar(contador_envolvente, total_envolventes, prefix = 'Creando ELS C envolvente:', suffix = 'Completado', length = 50)
-print()
-
-combo_name = "5. ENV ELS F"
-ret = SapModel.RespCombo.Add(combo_name, 1)
-comboNames = SapModel.RespCombo.GetNameList()
-patron = []
-for j in range(comboNames[0]):
-    if "ELS_F_" in comboNames[1][j]: patron.append(comboNames[1][j])  
-for i, name in enumerate(patron):
-    ret = SapModel.RespCombo.SetCaseList(combo_name, 1, name, 1)
-    contador_envolvente += 1
-    printProgressBar(contador_envolvente, total_envolventes, prefix = 'Creando ELS F envolvente:', suffix = 'Completado', length = 50)
-print()
-
-combo_name = "6. ENV ELS CP"
-ret = SapModel.RespCombo.Add(combo_name, 1)
-comboNames = SapModel.RespCombo.GetNameList()
-patron = []
-for j in range(comboNames[0]):
-    if "ELS_CP" in comboNames[1][j]: patron.append(comboNames[1][j])  
-for i, name in enumerate(patron):
-    ret = SapModel.RespCombo.SetCaseList(combo_name, 1, name, 1)
-    contador_envolvente += 1
-    printProgressBar(contador_envolvente, total_envolventes, prefix = 'Creando ELS CP envolvente:', suffix = 'Completado', length = 50)
-
-print()
-print(f"{VERDE}Envolventes creadas con éxito.{RESET}")
-
-extraer_combinaciones_a_excel(SapModel, ruta_excel)

+ 1 - 1
extraer_comb.py

@@ -1,6 +1,6 @@
 # ===================================================================
 # extraer_combos_sap.py
-# Función standalone para extraer combinaciones de SAP2000 con formato 100% idéntico al reporte oficial
+# Función standalone para extraer combinaciones de SAP2000 
 # ===================================================================
 
 import os