CAPITOLO 4 EXCEL MACRO
4.6 Generazione del Modello Geometrico su Straus7(API)
che definisce le caratteristiche geometriche che permetteranno di importare il modello in Straus7 mediante le API, di seguito descritte.
Prima fase
In primo luogo è necessario Caricare i Nodi, attraverso la subroutine chiamata Set_Nodi. Quest’ultima comprende al suo interno diverse istruzioni che vengono richiamate attraverso il comando“Call”.
Il flusso logico con cui si avviano è il seguente:
Set_Nodi (Inizio) - Call St7Init - Creazione di un nuovo modello
Call UnitaOpzioni - Definizione Unità di Misura Call Set Nodi_1 - Caricamento Nodi 1
Call Set Nodi_2 - Caricamento Nodi 2 Call Set Nodi_3 - Caricamento Nodi 3 Call Set Nodi_4 - Caricamento Nodi 4 Set_Nodi (Fine) – Salva e Chiudi il File
Set_Nodi (Inizio)
Prima di importare i Nodi è necessario definire un nuovo modello.
Si noti che nella programmazione delle macro, è necessario definire l’inizio e la fine delle subroutine.
L’inizio è indicato con:
Sub Nome Subroutine ()
La fine è indicata con:
End Sub
Inizialmente, sono state definite le “Variabili di tipo Stringa”(String) per memorizzare dati testuali quali nomi, indirizzi e annotazioni.
Dim percorso As String
Stringa contenente il percorso del file
Dim temporaneo As String
Stringa contenente il percorso per la directory dei files temporanei
Stringa contenente il nome del modello
Dim nome_modello As String
Altra Stringa contenente il nome del file
Dim nome_analisi As String
Stringa contenente il nome dei risultati dell’analisi del modello Inoltre sono state usati i seguenti tipi di variabile numerica:
Parola chiave Tipo di informazione Intervallo Numero di cifre decimali Integer Numeri Interi Da -32.768 a +32.767 Nessuno
Long Numeri interi Da –2.147.483.648 a +2.147.483.647 Nessuno Double Numeri con decimali in doppia precisione Valori negativi: da – 1,79769313486231E308 a – 4,94065645841247E- 324; valori positivi: da 4,94065645841247E-324 a 1,797693134862325E308 14
Tabella 4.33 - Caratteristiche dei tipi di variabile numerica più comuni | Adattato da Guccini, 2013
In seguito alle definizioni delle variabili String, qui sopra riportate, si segnala che in ogni Subroutine, in cui facciamo riferimento alle funzioni di richiamo di Straus7(API), è stata definita la variabile Integer che si chiama “errore”.
Dim errore As Integer
Variabile errore che contiene i messaggi di errore generati dalle API di Straus7.
Questa variabile, come verrà indicato nel paragrafo dedicato agli errori, permette di capire se la funzione di richiamo di Straus7 ha processato l’istruzione correttamente.
Successivamente alla definizione delle variabili, al nome della variabile è stata assegnata una determinata cella del foglio Excel, in modo da controllare questi valori a piacimento cambiando semplicemente il nome all’interno della cella.
Capitolo 4 98
Percorso = C31 temporaneo = C32
modello = C33
nome_modello = percorso & modello & “.st7” nome_analisi = percorso & modello & “.lsa”
Dove &, sta a significare l’unione di più stringhe per formarne una sola. Quindi definiti questi parametri, possiamo richiamare le funzioni di Straus7.
Sopra sono state definite le celle in cui andranno indicate le variabili String descritte in precedenza. Di seguito andremo a inizializzare le Straus7 API DLL mediante il comando “Call St7Init”.
La funzione API per la creazione di un nuovo modello è la seguente:
errore = St7NewFile(1, nome_modello, temporaneo) AE2 = errore
St7SaveFile (1) St7CloseFile (1)
End Sub
La funzione API è stata posta uguale alla variabile “errore”, a tale variabile è stata associata la cella del foglio Excel AE2. Se la funzione API non va a buon fine, si genera un numero a cui corrisponde un determinato errore nella cella designata. Se non ci sono problemi comparirà uno zero.
F
IL
E
Directory C:\Users\Matteo\Desktop\
Temporaneo C:\Users\Matteo\Desktop\temp
nome modello EXAMPLE
Tabella 4.34 – Illustrazione delle celle destinate a contenere il percorso della Directory e dei file temporanei e il nome del modello
UnitaOpzioni
Fino a questo punto è stata avviata la subroutine tramite Sub Set_Nodi(), che non è ancora stata chiusa. A questo punto è necessario richiamare, tramite la
funzione Call, la subroutine successiva che definisce le unità di misura e le opzioni:
Call UnitaOpzioni
Il codice viene mostrato di seguito:
Sub UnitaOpzioni ()
Dim I As Integer
Dim errore As Integer
'vettore dove inserire unità di misura' Dim sistema(5)2 As Long
For I = 0 To 5
sistema(I) = Cells(I + 2, 25).Value
Next I
'scrittura unità di misura’
errore = St7SetUnits(1, sistema(0))3
AE6 = errore Unità di misura Lunghezza mm 2 Forza N 0 Stress Pa 0 Massa kg 0 Temperatura °C 0 Energia J 0
Tabella 4.35 – Unità di misura
Ad ogni numero corrisponde un unità di misura diversa, qui sotto sono elencate le variabili:
Rem Unit Types - LENGTH Public Const luMETRE = 0 Public Const luCENTIMETRE = 1
Public Const luMILLIMETRE = 2 Public Const luFOOT = 3
Public Const luINCH = 4 Rem Unit Types - FORCE Public Const fuNEWTON = 0 Public Const fuKILONEWTON = 1 Public Const fuMEGANEWTON = 2
Public Const fuKILOFORCE = 3 Public Const fuPOUNDFORCE = 4 Public Const fuTONNEFORCE = 5
Public Const fuKIPFORCE = 6
2 sistema(5) sono 6 valori da 0 a 5, è un Array.
3
Capitolo 4 100
Rem Unit Types - STRESS Public Const suPASCAL = 0 Public Const suKILOPASCAL = 1 Public Const suMEGAPASCAL = 2
Public Const suKSCm = 3 Public Const suPSI = 4 Public Const suKSI = 5 Public Const suPSF = 6 Rem Unit Types - MASS Public Const muKILOGRAM = 0
Public Const muTONNE = 1 Public Const muGRAM = 2 Public Const muPOUND = 3
Public Const muSLUG = 4 Rem Unit Types - TEMPERATURE
Public Const tuCELSIUS = 0 Public Const tuFAHRENHEIT = 1
Public Const tuKELVIN = 2 Rem Unit Types - ENERGY Public Const euJOULE = 0
Public Const euBTU = 1 Public Const euFTLBF = 2 Public Const euCALORIE = 3
'definizione delle opzioni' Dim opzioni(13) As Long For I = 0 To 13
opzioni(I) = Cells(I + 2, 28).Value
Next I
'vettore dove inserire le tolleranze' Dim tollerance(2)4 As Double
For I = 0 To 2
tollerance(I) = Cells(I + 18, 28).Value
Next I
'scrittura tollerance’
errore = St7SetToolOptions(1, opzioni(0), tollerance(0)) AE3 = errore
Call SetNodi_1
End Sub
4
Setup Opzioni ipToolOptsElementTolType ipToolOptsGeometryAccuracyType ipToolOptsGeometryFeatureType ipToolOptsZipMesh 2 ipToolOptsNodeCoordinate ipToolOptsNodeAttributeKeep ipToolOptsAllowZeroLengthLinks ipToolOptsAllowZeroLengthBeams ipToolOptsAllowSameProperty ipToolOptsCompatibleTriangle ipToolOptsSubdivideBeams ipToolOptsPlateAxisAlign ipToolOptsCopyMode ipToolOptsAutoCreateProperties ipToolOptsElementTol ipToolOptsGeometryAccuracy ipToolOptsGeometryFeatureLength
Tabella 4.36 – Definizione delle Opzioni per mantenere i nodi separati
Tra tutte queste opzioni indicate in Tabella 4.36, a noi interessa modificarne solo una, la ipToolOptsZipMesh che ci permetterà di creare due nodi nello stesso punto, senza che il programma in automatico le unisca in uno solo. Quindi nella casella indicata, inseriremo il numero 2, che corrisponde a zmOnRequest.
Capitolo 4 102
Lasciando gli altri spazi vuoti, il programma prenderà in automatico il valore zero e manterrà le opzioni di default.
Rem Tool Options - Integers
Public Const ipToolOptsElementTolType = 0 Public Const ipToolOptsGeometryAccuracyType = 1
Public Const ipToolOptsGeometryFeatureType = 2 Public Const ipToolOptsZipMesh = 3 Public Const ipToolOptsNodeCoordinate = 4 Public Const ipToolOptsNodeAttributeKeep = 5 Public Const ipToolOptsAllowZeroLengthLinks = 6 Public Const ipToolOptsAllowZeroLengthBeams = 7
Public Const ipToolOptsAllowSameProperty = 8 Public Const ipToolOptsCompatibleTriangle = 9 Public Const ipToolOptsSubdivideBeams = 10
Public Const ipToolOptsPlateAxisAlign = 11 Public Const ipToolOptsCopyMode = 12 Public Const ipToolOptsAutoCreateProperties = 13
Rem Tool Options - Mesh Zipping
Public Const zmAsNeeded = 0 Public Const zmOnSave = 1
Public Const zmOnRequest = 2 sceglieremo questa opzione, il programma unisce i punti, solo su richiesta
Questa Opzione è fondamentale per la buona riuscita della creazione dei Nodi.
SetNodi_1
Ora, prima di completare la subroutine con “End Sub”, richiamiamo Call SetNodi_1. Così facendo, si permette al codice di gestire e elaborare il file Straus7 creato in prima istanza. Questa procedura verrà ripetuta per tutti i SetNodi presenti.
Sub SetNodi_1()
'lettura coordinate nodi'
Dim x As Long, m As Long, f As Long
Dim errore As Integer Dim nodo As Long
m = 4
For x = 1 To Tot N° nodo VERTICALI
For f = 1 To N° nodo ORIZZ Elem1
nodo = Cells(x + N°RigaElem1, 1 + (f - 1) * m).Value
Dim XYZ(2) As Double
XYZ(0) = Cells(x + N°RigaElem1, 2 + (f - 1) * m).Value XYZ(1) = Cells(x + N°RigaElem1, 3 + (f - 1) * m).Value XYZ(2) = Cells(x + N°RigaElem1, 4 + (f - 1) * m).Value errore = St7SetNodeXYZ(1, nodo, XYZ(0))
AE4 = errore Next f Next x Call SetNodi_2 End Sub SetNodi_2 Sub SetNodi_2()
'lettura coordinate nodi'
Dim x As Long, m As Long, f As Long
Dim errore As Integer Dim nodo As Long
m = 4
For x = 1 To Tot N° nodo VERTICALI
For f = 1 To N° nodo ORIZZ Elem5
nodo = Cells(x + N°RigaElem5, 1 + (f - 1) * m).Value
Dim XYZ(2) As Double
XYZ(0) = Cells(x + N°RigaElem5, 2 + (f - 1) * m).Value XYZ(1) = Cells(x + N°RigaElem5, 3 + (f - 1) * m).Value XYZ(2) = Cells(x + N°RigaElem5, 4 + (f - 1) * m).Value errore = St7SetNodeXYZ(1, nodo, XYZ(0))
AF4 = errore Next f Next x Call SetNodi_3 End Sub SetNodi_3 Sub SetNodi_3()
'lettura coordinate nodi'
Dim x As Long, m As Long, f As Long
Dim errore As Integer Dim nodo As Long
m = 4
For x = 1 To Tot N° nodo VERTICALI
For f = 1 To N° nodo ORIZZ Elem9
nodo = Cells(x + N°RigaElem9, 1 + (f - 1) * m).Value
Dim XYZ(2) As Double
XYZ(0) = Cells(x + N°RigaElem9, 2 + (f - 1) * m).Value XYZ(1) = Cells(x + N°RigaElem9, 3 + (f - 1) * m).Value XYZ(2) = Cells(x + N°RigaElem9, 4 + (f - 1) * m).Value errore = St7SetNodeXYZ(1, nodo, XYZ(0))
AG4 = errore
Next f
Next x
Capitolo 4 104
End Sub
SetNodi_4
Sub SetNodi_4()
'lettura coordinate nodi'
Dim x As Long, m As Long, f As Long
Dim errore As Integer Dim nodo As Long
m = 4
For x = 1 To Tot N° nodo VERTICALI
For f = 1 To N° nodo ORIZZ Elem13
nodo = Cells(x + N°RigaElem13, 1 + (f - 1) * m).Value
Dim XYZ(2) As Double
XYZ(0) = Cells(x + N°RigaElem13, 2 + (f - 1) * m).Value XYZ(1) = Cells(x + N°RigaElem13, 3 + (f - 1) * m).Value XYZ(2) = Cells(x + N°RigaElem13, 4 + (f - 1) * m).Value errore = St7SetNodeXYZ(1, nodo, XYZ(0))
AH4 = errore
Next f
Next x
End Sub
Alla fine del codice SetNodi_4, non è presenta la funzione Call. Quindi la subroutine termina con End Sub e l’istruzione ritorna alla subroutine Set_Nodi, che conclude il processo salvando e chiudendo il file.
St7SaveFile (1) St7CloseFile (1)
End Sub
Seconda Fase
A questo punto è necessario importare le Plate. La subroutine si chiama Set_Plate e si collega ad altre subroutine attraverso il comando chiamata “Call”. Il flusso logico con cui si avviano le subroutine è il seguente:
Set_Plate (Inizio) - Call St7Init - Apertura del modello creato precedentemente
Call SetPlate_1 - Caricamento Plate 1 Call SetPlate_2_1 - Caricamento Plate 2_1 Call SetPlate_2_2 - Caricamento Plate 2_2
Call SetPlate_3 - Caricamento Plate 3 Call SetPlate_4 - Caricamento Plate 4 Set_Nodi (Fine) – Salva e Chiudi il File
La prima routine è uguale a quella per il caricamento dei nodi, ma invece di generare un nuovo modello (St7NewFile), si apre il modello appena creato (St7OpenFile) nelle istruzioni Set_Nodi.
SetPlate
Sub Set_Plate()
Dim errore As Integer
Dim percorso As String, temporaneo As String, modello As
String, nome_modello As String, nome_analisi As String
percorso = C31 temporaneo = C32 modello = C33
nome_modello = percorso & modello & ".st7" nome_analisi = percorso & modello & ".lsa"
Call St7Init
errore = St7OpenFile(1, nome_modello, temporaneo) AE7= errore Call SetPlate_1 St7SaveFile (1) St7CloseFile (1) End Sub SetPlate_1 Sub SetPlate_1()
'definizione elemento Plate'
Dim n As Long, m As Long, f As Long
For n = 1 To N° PlateVert
For m = 1 To IntervPlate1.1,1.2 f = 6
Dim errore As Integer
Dim elemento As Long , nodipl(4) As Long Dim numeroproprieta As Integer
'numero proprietà della Plate'
numeroproprieta = 1
'lettura numero dell’elemento Plate’
elemento = Cells(N° RigaPlate1.2 + n, 1 + f * (m - 1)).Value
'lettura numero elementi contenente la Plate'
nodipl(0) = Cells(N° RigaPlate1.2 + n, 2 + f * (m - 1)).Value
'lettura numero End 1 della Plate'
nodipl(1) = Cells(N° RigaPlate1.2 + n, 3 + f * (m - 1)).Value
'lettura numero End 2 della Plate'
nodipl(2) = Cells(N° RigaPlate1.2 + n, 4 + f * (m - 1)).Value
'lettura numero End 3 della Plate'
nodipl(3) = Cells(N° RigaPlate1.2 + n, 5 + f * (m - 1)).Value
'lettura numero End 4 della Plate'
nodipl(4) = Cells(N° RigaPlate1.2 + n, 6 + f * (m - 1)).Value
Capitolo 4 106 errore = St7SetElementConnection(1, 2, elemento,
numeroproprieta, nodipl(0)) AE5 = errore Next m Next n Call SetPlate_2_1 End Sub SetPlate_2_1 Sub SetPlate_2_1()
'definizione elemento Plate'
Dim n As Long, m As Long, f As Long
For n = 1 To N° PlateVert
For m = 1 To IntervPlate2.1,2.2 f = 6
Dim errore As Integer
Dim elemento As Long, nodipl(4) As Long Dim numeroproprieta As Integer
numeroproprieta = 1
elemento = Cells(N° RigaPlate2.1 + n, 1 + f * (m - 1)).Value nodipl(0) = Cells(N° RigaPlate2.1 + n, 2 + f * (m - 1)).Value nodipl(1) = Cells(N° RigaPlate2.1 + n, 3 + f * (m - 1)).Value nodipl(2) = Cells(N° RigaPlate2.1 + n, 4 + f * (m - 1)).Value nodipl(3) = Cells(N° RigaPlate2.1 + n, 5 + f * (m - 1)).Value nodipl(4) = Cells(N° RigaPlate2.1 + n, 6 + f * (m -
1)).Value
errore = St7SetElementConnection(1, 2, elemento, numeroproprieta, nodipl(0)) AE5 = errore Next m Next n Call SetPlate_2_2 End Sub SetPlate_2_2 Sub SetPlate_2_2()
'definizione elemento Plate'
Dim n As Long, m As Long, f As Long
For n = 1 To N° PlateVert
For m = 1 To IntervPlate2.3 f = 6
Dim errore As Integer
Dim elemento As Long, nodipl(4) As Long Dim numeroproprieta As Integer
numeroproprieta = 1
elemento = Cells(N° RigaPlate2.3 + n, 1 + f * (m - 1)).Value nodipl(0) = Cells(N° RigaPlate2.3 + n, 2 + f * (m -
1)).Value
nodipl(1) = Cells(N° RigaPlate2.3 + n, 3 + f * (m - 1)).Value
nodipl(2) = Cells(N° RigaPlate2.3 + n, 4 + f * (m - 1)).Value
nodipl(3) = Cells(N° RigaPlate2.3 + n, 5 + f * (m - 1)).Value
nodipl(4) = Cells(N° RigaPlate2.3 + n, 6 + f * (m - 1)).Value
errore = St7SetElementConnection(1, 2, elemento, numeroproprieta, nodipl(0)) AE5 = errore Next m Next n Call SetPlate_3 End Sub SetPlate_3 Sub SetPlate_3()
'definizione elemento Plate'
Dim n As Long, m As Long, f As Long
For n = 1 To N° PlateVert
For m = 1 To IntervPlate3 f = 6
Dim errore As Integer
Dim elemento As Long, nodipl(4) As Long Dim numeroproprieta As Integer
numeroproprieta = 1
elemento = Cells(N° RigaPlate 3 + n, 1 + f * (m - 1)).Value nodipl(0) = Cells(N° RigaPlate 3 + n, 2 + f * (m -
1)).Value
nodipl(1) = Cells(N° RigaPlate 3 + n, 3 + f * (m - 1)).Value nodipl(2) = Cells(N° RigaPlate 3 + n, 4 + f * (m - 1)).Value nodipl(3) = Cells(N° RigaPlate 3 + n, 5 + f * (m - 1)).Value nodipl(4) = Cells(N° RigaPlate 3 + n, 6 + f * (m - 1)).Value errore = St7SetElementConnection(1, 2, elemento,
numeroproprieta, nodipl(0)) AE5 = errore Next m Next n Call SetPlate_4 End Sub SetPlate_4 Sub SetPlate_4()
'definizione elemento Plate'
Dim n As Long, m As Long, f As Long
For n = 1 To N° PlateVert
For m = 1 To IntervPlate4 f = 6
Dim errore As Integer
Dim elemento As Long, nodipl(4) As Long Dim numeroproprieta As Integer
numeroproprieta = 1
elemento = Cells(N° RigaPlate 4 + n, 1 + f * (m - 1)).Value nodipl(0) = Cells(N° RigaPlate 4 + n, 2 + f * (m - 1)).Value
Capitolo 4 108 nodipl(1) = Cells(N° RigaPlate 4 + n, 3 + f * (m - 1)).Value nodipl(2) = Cells(N° RigaPlate 4 + n, 4 + f * (m - 1)).Value nodipl(3) = Cells(N° RigaPlate 4 + n, 5 + f * (m - 1)).Value nodipl(4) = Cells(N° RigaPlate 4 + n, 6 + f * (m - 1)).Value errore = St7SetElementConnection(1, 2, elemento,
numeroproprieta, nodipl(0)) AE5 = errore
Next m
Next n
End Sub