Sélection par commentaire
La méthode la plus simple consiste à assigner des commentaires lors de la création des éléments. L'utilisateur peut ensuite rechercher ces commentaires. La fonction suivante permet de rechercher les barres d'après leur commentaire et renvoie les numéros de barre ainsi identifiés :
Function getMemberNosByComment(members() As RFEM5.Member, comment As String) As Integer()
Dim intArr() As Integer
Dim i As Long
Dim j As Long
j = 0
ReDim intArr(0 To 0)
' loop over members
For i = 0 To UBound(members, 1)
If (members(i).comment = comment) Then
' size if integer array is increased by 1
ReDim Preserve intArr(0 To j)
intArr(j) = members(i).no
j = j + 1
End If
Next i
' return integer array
getMemberNosByComment = intArr
End Function
La fonction a une boucle sur les barres transférées et le numéro de barre est ajouté au champ Nombre entier (Integer) si la chaîne dans « comment » et le commentaire de la barre correspondent. Enfin, le champ Nombre entier avec tous les numéros de barre est renvoyé.
Sélection des nœuds d'extrémité de barre
Les éléments sont sélectionnés dans le logiciel et donc via l'interface COM à l'aide de chaînes de caractères. Les nœuds associés à une ligne sont par exemple transférés via une chaîne de caractères dans laquelle les numéros de nœud sont séparés par des virgules. L'utilisation de chaînes de caractères nécessite la conversion en valeurs numériques lors de la programmation et inversement. La fonction suivante permet de convertir les numéros de barre déterminés à partir de la fonction ci-dessus en une chaîne de caractères. Chaque numéro de barre est converti en caractères à l'aide de la fonction CStr et une virgule est ajoutée à la chaîne après chaque chiffre. RFEM/RSTAB ignore la virgule redondante à la fin de la chaîne, il n'est donc pas nécessaire de la supprimer.
Function intArrToStr(intArr() As Integer) As String
Dim str As String
Dim i As Long
For i = 0 To UBound(intArr, 1)
str = str + CStr(intArr(i)) + ","
Next i
intArrToStr = str
End Function
Cette fonction permet de sélectionner les barres préalablement filtrées à l'aide de leurs commentaires via l'interface COM.
' select members by comment
Dim mems() As RFEM5.Member
Dim mem_nos() As Integer
Dim str As String
str = "test comment"
mem_nos = getMemberNosByComment(mems, str)
iModelData.EnableSelections (True)
str = intArrToStr(mem_nos)
iModelData.SelectObjects MemberObject, str
Sélectionner des éléments spécifiques n'est souvent pas suffisant car des éléments subordonnés sont requis. L'exemple suivant montre comment trouver les nœuds de début de barre. Une ligne appartenant à chaque barre a été choisie ici car cette opération est légèrement plus complexe dans RFEM que dans RSTAB.
La première étape consiste à trouver les numéros des lignes appartenant aux barres. La fonction suivante suppose que les numéros de barre sont déjà disponibles et permet de rechercher les numéros de ligne correspondants :
Function getLineNosByMemberNos(members() As RFEM5.Member, member_nos() As Integer) As Integer()
Dim intArr() As Integer
Dim i As Long
Dim j As Long
Dim k As Long
k = 0
ReDim intArr(0 To 0)
For i = 0 To UBound(members, 1)
For j = 0 To UBound(member_nos, 1)
If (members(i).no = member_nos(j)) Then
' increase array size by 1
ReDim Preserve intArr(0 To k)
intArr(k) = members(i).LineNo
k = k + 1
' exit loop over member_nos
Exit For
End If
Next j
Next i
getLineNosByMemberNos = intArr
End Function
Cette fonction a deux boucles imbriquées : une boucle principale pour les barres et une boucle subordonnée pour les numéros de barre. Le champ des numéros de barre est complètement parcouru par la boucle pour chaque barre. La boucle subordonnée est abandonnée dès que les numéros de barre correspondent afin d'accélérer ce processus. Chaque fois qu'une correspondance est trouvée, un élément est ajouté au champ contenant les numéros de ligne et le nouveau numéro est ajouté (k est l'indice des numéros de ligne trouvés).
Une autre fonction est requise pour trouver le nœud de début de la ligne correspondant à la barre. Cette fonction doit parcourir les lignes et lire le nœud de début si les lignes correspondent aux numéros de ligne indiqués. Les numéros de nœud sont enregistrés dans une chaîne et une nouvelle fonction est donc nécessaire pour convertir cette chaîne en un champ contenant les numéros.
Function strToIntArr(intList As String) As Integer()
' possible chars "1-9 ; - ,"
' example: 1-4,5;100 > 1,2,3,4,5,100
Dim ints() As Integer
Dim tmpInts() As Integer
ReDim ints(0)
Dim span As Boolean
Dim curInt As String
curInt = ""
Dim i As Integer
i = 0
Dim j As Integer
Dim curChar As String
Do While (i < Len(intList))
curChar = Mid(intList, i + 1, 1)
' if string contains "-" a span is noted
If (curChar = "-") Then
span = True
tmpInts = ints
ReDim Preserve tmpInts(0 To UBound(tmpInts, 1) + 1)
tmpInts(UBound(tmpInts, 1) - 1) = CInt(curInt)
ints = tmpInts
curInt = ""
' if last char is reached or a comma or a semicolon is the next char
ElseIf ((curChar = ",") Or (curChar = ";") Or (i = Len(intList) - 1)) Then
' last char is reached, integer or span are terminated
If (i = Len(intList) - 1) Then
curInt = curInt & curChar
End If
' treat the span
If span Then
' create all integers between the span
Dim firstNum As Integer
Dim lastNum As Integer
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
' extend ints and add new numbers to array
tmpInts = ints
ReDim Preserve tmpInts(0 To UBound(tmpInts, 1) + (lastNum - firstNum))
For j = 0 To (lastNum - firstNum) - 1
tmpInts(UBound(ints, 1) + j) = j + firstNum + 1
Next j
ints = tmpInts
span = False
' add new digit
Else
'extend ints and add new number to ints
tmpInts = ints
ReDim Preserve tmpInts(0 To UBound(tmpInts, 1) + 1)
tmpInts(UBound(tmpInts, 1) - 1) = CInt(curInt)
ints = tmpInts
curInt = ""
End If
Else
curInt = curInt & curChar
End If
i = i + 1
Loop
' array is one element too long and is decreased
ReDim Preserve ints(0 To UBound(ints, 1) - 1)
strToIntArr = ints
End Function
Cette fonction parcourt la chaîne et analyse chaque caractère. S'il y a un ou plusieurs nombres, ils sont collectés jusqu'au prochain caractère ou la fin de la chaîne. Lorsqu'un trait d'union est atteint, une série de nombres est reconnue et les nombres intermédiaires sont générés automatiquement.
La fonction d'extraction du point de début d'une ligne peut alors être créée et est donc très claire.
Function 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 As Long
Dim k As Long
k = 0
ReDim intArr(0 To 0)
For i = 0 To UBound(line_nos, 1)
For j = 0 To UBound(lines, 1)
If (lines(j).no = line_nos(i)) Then
' add found line number to array
ReDim Preserve intArr(0 To k)
str = lines(j).NodeList
tmpIntArr = strToIntArr(str)
intArr(k) = tmpIntArr(0)
k = k + 1
' exit loop over line_nos_cpy
Exit For
End If
Next j
Next i
getLineStartNodeNosByLineNos = intArr
End Function
Cette fonction contient deux boucles imbriquées, comme la fonction getLineNosByMemberNos. Cette séquence est très importante car elle permet de conserver l'assignation des nœuds aux lignes. La boucle externe parcourt les numéros de ligne et, si une ligne dans la boucle interne correspond, la fonction strToIntArr est utilisée pour extraire les numéros des nœuds. C'est le premier de ces numéros qui est d'ailleurs utilisé ici.
La procédure complète pour obtenir les nœuds de début est indiquée ci-après. Les numéros de ligne des barres ayant les numéros correspondants sont extraits, ce qui permet d'obtenir les nœuds de début de ligne.
' select start nodes from members
' get line numbers from all members
Dim line_nos() As Integer
line_nos = getLineNosByMemberNos(mems, mem_nos)
' get start numbers from all lines
Dim stNodes_nos() As Integer
stNodes_nos = getLineStartNodeNosByLineNos(lines, line_nos)
Résumé et perspectives
La fonction getLineNosByMemberNos constitue une base pour d'autres fonctions de sélection et pour la fonction getLineStartNodeNosByLineNos. Ce patron permet par exemple de trouver des charges de barres. Les fonctions strToIntArr et intArrToStr servent quant à elles à convertir la sélection à l'aide de chaînes de caractères depuis RFEM en champs numériques.
La sélection via les coordonnées est une autre option. Ainsi, l'utilisateur peut par exemple spécifier un espace défini et tous les éléments de cet espace peuvent être sélectionnés. Ce type de sélection sera décrit dans un autre article.