1932x
001596
2019-10-23

Metodi per la selezione degli elementi tramite l'interfaccia COM

Quando si modificano gli elementi tramite l'interfaccia COM, la selezione di elementi è spesso un problema perché non può essere eseguita visivamente tramite la finestra di lavoro. Gerade bei Modellen, welche über die Programmoberfläche erzeugt wurden und dann über ein eigenes Programm modifiziert werden sollen, kann die Auswahl schwierig sein. Neben der Ausnahme, dass die Auswahl zuvor über RFEM getroffen wurde, gibt es mehrere Alternativen für die Programmierung.

Selezione per commento

La cosa più semplice potrebbe essere che i commenti sono stati assegnati durante la creazione degli elementi, che possono quindi essere ricercati in modo specifico. Nel testo seguente, viene mostrato un esempio di una funzione che ricerca le aste in base al loro commento e restituisce i numeri delle aste trovati:

Funzione getMemberNosByComment(aste() As RFEM5.Member, commento As String) As Integer()
Dim intArr() As Integer
Dim i As Long
Dim j Fino a quando
j = 0
ReDim intArr(0 To 0)
' loop sulle aste
Per i = 0 A UBound(aste, 1)
Se (aste(i).comment = commento) Then
' size se la matrice intera è aumentata di 1
ReDim Preserve intArr(0 To j)
intArr(j) = aste(i).n
j = j + 1
End If
Successivo i
' restituisce una matrice intera
getMemberNosByComment = intArr
Fine Funzione

La funzione ha un ciclo sulle aste trasferite e se la stringa in "commento" e il commento dell'asta corrispondono, il numero dell'asta viene aggiunto al campo intero. Infine, viene restituito il campo intero con tutti i numeri delle aste.

Selezione dei nodi finali dell'asta

La selezione degli elementi nel programma, e quindi tramite l'interfaccia COM, viene eseguita utilizzando le stringhe. Per una linea, ad esempio, i nodi relativi sono trasferiti tramite una stringa in cui i numeri dei nodi sono separati da virgole. L'utilizzo di stringhe richiede la conversione in valori numerici durante la programmazione, e viceversa. La seguente funzione, quindi, presenta un modo per convertire i numeri delle aste determinati con la funzione sopra in una stringa. I numeri delle aste sono convertiti individualmente in caratteri utilizzando la funzione CStr e, dopo ogni numero, viene aggiunta una virgola alla stringa. RFEM/RSTAB ignora la virgola ridondante alla fine della stringa, che può quindi rimanere.

Funzione intArrToStr(intArr() As Integer) As String
Dim str As String
Dim i As Long
    
Per i = 0 A UBound(intArr, 1)
str = str + CStr(intArr(i)) + ","
Successivo i
    
intArrToStr = str
Fine Funzione

Questa funzione ora consente la selezione delle aste filtrate per commento tramite l'interfaccia COM.

' seleziona le aste per commento
Dim mems() As RFEM5.Member
Dim mem_nos() As Integer
Dim str As String
    
str = "commento di prova"
mem_nos = getMemberNosByComment(mems, str)
    
iModelData.EnableSelections (True)
    
str = intArrToStr(mem_nos)
iModelData.SelectObjects MemberObject, str

Spesso, non è sufficiente selezionare solo elementi specifici; sono necessari elementi subordinati. L'esempio seguente mostra come trovare i nodi iniziali di un'asta. Poiché questo si rivela un po' più difficile in RFEM che in RSTAB, poiché una linea appartiene a ogni asta, è stato scelto questo metodo.

Innanzitutto, è necessario trovare i numeri delle linee appartenenti alle aste. La seguente funzione presuppone che i numeri delle aste siano già disponibili e ricerca i numeri di linea relativi.

Funzione getLineNosByMemberNos( Members() As RFEM5.Member, Member_nos() As Integer) As Integer()
    
Dim intArr() As Integer
Dim i As Long
Dim j Fino a quando
Dim k Finché
    
k = 0
ReDim intArr(0 To 0)
    
Per i = 0 A UBound(aste, 1)
Per j = 0 A UBound(member_nos, 1)
Se (aste(i).no = asta_nos(j)) Then
' aumenta le dimensioni dell'array di 1
ReDim Preserve intArr(0 To k)
intArr(k) = aste(i).Lineanr
k = k + 1
' esci dal ciclo su aste_nos
Esci per
End If
        
Successivo j
Successivo i
    
getLineNosByMemberNos = intArr
    
Fine Funzione

Questa funzione ha due loop nidificati. Il ciclo principale passa attraverso le aste e il ciclo subordinato attraverso i numeri delle aste. Per ogni asta, il campo contenente i numeri dell'asta viene visualizzato in modo completo. Per accelerare questo processo, il sotto-ciclo viene lasciato non appena i numeri delle aste corrispondono. Ogni volta che c'è una corrispondenza, un elemento viene aggiunto al campo contenente i numeri delle linee e viene aggiunto il nuovo numero (k è l'indice per i numeri delle linee trovate).

Per trovare il nodo iniziale della linea o dell'asta, è necessaria un'altra funzione. Questa funzione deve passare attraverso le linee e, se corrispondono ai numeri di linea indicati, leggere il nodo iniziale. Poiché i numeri di nodo sono memorizzati in una stringa, è necessaria una nuova funzione per convertire la stringa in un campo numerico.

Funzione strToIntArr(intList As String) As Integer()
' possibili caratteri "1-9 ; - ,"
' esempio: 1-4,5;100 > 1,2,3,4,5,100
Dim ints() As Integer
Dim tmpInts() As Integer
ReDim ints(0)
    
Dim campata Come booleano
Dim curInt As String
curInt = ""
Dim i come intero
i = 0
Dim j As intero
Dim curChar As String
    
Do While (i < Len(intList))
curChar = Mid(intList, i + 1, 1)
        
' se la stringa contiene "-" viene notato un intervallo
If (curChar = "-") Then
        
span = Vero
tmpInts = ints
ReDim Preserve tmpInts(0 To UBound(tmpInts, 1) + 1)
tmpInts(UBound(tmpInts, 1) - 1) = CInt(curInt)
ints = tmpInts
curInt = ""
' se è stato raggiunto l'ultimo carattere o una virgola o un punto e virgola è il carattere successivo
ElseIf ((curChar = ",") Or (curChar = ";") Or (i = Len(intList) - 1)) Then
        
' è stato raggiunto l'ultimo carattere, il numero intero o lo span sono terminati
Se (i = Len(intList) - 1) Then
curInt = curInt & curChar
End If
            
' tratta la campata
Se intervallo Allora
' crea tutti i numeri interi tra l'intervallo
Dim firstNum As Integer
Dim lastNum As intero
firstNum = ints(UBound(ints, 1) - 1)
lastNum = CInt(curInt)
curInt = ""
                
If (firstNum > lastNum) Then
Dim tmp1 As Integer
tmp1 = lastNum
lastNum = firstNum
firstNum = tmp1
ints(UBound(ints, 1) - 1) = firstNum
                    
End If
                
' estende gli int e aggiunge nuovi numeri all'array
tmpInts = ints
ReDim Preserve tmpInts(0 To UBound(tmpInts, 1) + (lastNum - firstNum))
                
Per j = 0 A (lastNum - firstNum) - 1
tmpInts(UBound(ints, 1) + j) = j + firstNum + 1
Successivo j
                
ints = tmpInts
span = Falso
            
' aggiungi nuova cifra
Altro
'extend ints e aggiungi un nuovo numero a ints
tmpInts = ints
ReDim Preserve tmpInts(0 To UBound(tmpInts, 1) + 1)
tmpInts(UBound(tmpInts, 1) - 1) = CInt(curInt)
ints = tmpInts
curInt = ""
End If
        
Altro
        
curInt = curInt & curChar
End If
    
i = i + 1
Ciclo
    
' array è un elemento di troppo lungo ed è diminuito
ReDim Preserve ints(0 To UBound(ints, 1) - 1)
    
strToIntArr = ints
Fine Funzione

Questa funzione attraversa la stringa e analizza ogni carattere. Se il carattere contiene uno o più numeri, questi vengono raccolti fino a quando non viene raggiunto un altro carattere o la fine. Quando viene raggiunto un trattino, una serie/intervallo di numeri viene riconosciuta ei numeri intermedi sono generati automaticamente.

Ora la funzione vera e propria per estrarre il punto iniziale di una linea può essere creata ed è molto chiara.

Funzione getLineStartNodeNosByLineNos(lines() As RFEM5.RfLine, line_nos() As Integer) As Integer()
Dim intArr() As Integer
Dim tmpIntArr() As Integer
Dim str As String
Dim i As Long
Dim j Fino a quando
Dim k Finché
    
k = 0
ReDim intArr(0 To 0)
    
Per i = 0 A UBound(line_nos, 1)
Per j = 0 A UBound(linee, 1)
If (lines(j).no = line_nos(i)) Then
' aggiungi il numero della linea trovata all'array
ReDim Preserve intArr(0 To k)
str = linee(j).NodeList
tmpIntArr = strToIntArr(str)
intArr(k) = tmpIntArr(0)
k = k + 1
' esci dal ciclo su line_nos_cpy
Esci per
End If
        
Successivo j
Successivo i
    
getLineStartNodeNosByLineNos = intArr
Fine Funzione

Ancora una volta, ci sono due loop nidificati, come nella funzione getLineNosByMemberNos. Questa volta, la sequenza è molto importante perché altrimenti l'assegnazione dei nodi alle linee andrà persa. Il ciclo esterno scorre i numeri delle linee e, se una linea all'interno del ciclo interno è una corrispondenza, la funzione strToIntArr viene utilizzata per estrarre i numeri dei nodi, di cui il primo è utilizzato qui.

L'intera procedura per ottenere i nodi iniziali è quindi la seguente. Innanzitutto, vengono presi i numeri di linea delle aste con i numeri delle aste corrispondenti, seguiti dai nodi iniziali della linea.

' seleziona nodi iniziali dalle aste
' ottiene i numeri delle linee da tutte le aste
Dim line_nos() As Integer
line_nos = getLineNosByMemberNos(mems, mem_nos)
' ottiene i numeri iniziali da tutte le linee
Dim stNodes_nos() As Integer
stNodes_nos = getLineStartNodeNosByLineNos(linee, line_nos)

Riepilogo e prospettive

La funzione getLineNosByMemberNos è la base per ulteriori funzioni di selezione, proprio come con la funzione getLineStartNodeNosByLineNos. Utilizzando questo modello, è possibile, ad esempio, trovare carichi per le aste. Le funzioni strToIntArr e intArrToStr sono disponibili anche come strumenti per convertire la selezione di RFEM basata su stringhe in campi numerici.

Un'altra opzione è la selezione tramite le coordinate. Ad esempio, è possibile specificare uno spazio definito e selezionare tutti gli elementi all'interno di tale spazio. Questa forma di selezione sarà descritta in un articolo futuro.


Autore

Il signor Günthel fornisce supporto tecnico per i clienti di Dlubal Software e si prende cura delle loro richieste.

Link
Download