1926x
001596
23.10.2019

Méthodes de sélection d'éléments via l'interface COM

La sélection d'éléments lors de leur modification via l'interface COM pose souvent problème car elle ne peut pas être effectuée visuellement à l'aide de la fenêtre de travail. Cette opération peut être délicate, notamment pour les modèles créés à l'aide de l'interface du programme et qui doivent ensuite être modifiés avec un programme distinct. Cette sélection peut avoir été effectuée via RFEM, mais il existe plusieurs autres possibilités de programmation.

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.


Auteur

M. Günthel fournit une assistance technique aux clients de Dlubal Software.

Liens
Téléchargements