2242x
001596
2019-05-13

Métodos para seleção de elementos através da interface COM

Ao editar elementos através da interface COM, a seleção de elementos muitas vezes apresenta um problema, pois não pode ser realizada visualmente através da janela de trabalho. A seleção pode ser difícil especialmente em modelos que foram gerados através da interface do programa e que depois vão ser modificados por um programa separado. Além da exceção onde a seleção foi feita anteriormente através do RFEM, existem várias alternativas para a programação.

Seleção por comentário

A maneira provavelmente mais simples é, ao criar elementos são atribuídos comentários que podem ser pesquisados especificamente. A seguir, é apresentada uma função exemplar, que pesquisa barras através do comentário e retorna os números das barras encontradas:

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 of 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

A função tem um loop sobre as barras transferidas e, se houver uma correspondência entre a string em "comment" e o comentário da barra, o número da barra é adicionado ao campo de inteiros. No final, o campo de inteiros com todos os números de barras é retornado.

Seleção de nós de extremidade da barra

A seleção de elementos no programa e, portanto, também pela interface COM é realizada usando strings. Por exemplo, para uma linha, os nós correspondentes são transferidos por uma string, onde os números dos nós são armazenados separados por vírgulas. O uso de strings requer a conversão em valores numéricos durante a programação e vice-versa. A função seguinte apresenta uma foram de converter os números de barras determinados pela função acima em uma string. Os números das barras são convertidos individualmente em caracteres através da função CStr e, após cada número, uma é adicionada vírgula à string. A vírgula desnecessária no final da string é ignorada pelo RFEM/RSTAB e, portanto, pode ser mantida.

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

Com a ajuda desta função, agora é possível selecionar as barras filtradas por comentário através da 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

Geralmente, não basta apenas selecionar certos elementos, são necessários elementos subordinados. O exemplo seguinte apresenta como encontrar os nós iniciais de uma barra. Uma vez que este processo é mais no RFEM do que no RSTAB, porque uma linha pertence a cada barra, foi escolhido este método.

Primeiro, é necessário encontrar os números das linhas pertencentes às barras. A função a seguir assume que os números das barras já estão disponíveis e pesquisa os números das linhas correspondentes.

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

Esta função possui dois loops. O ciclo principal percorre as barras e o ciclo subordinado percorre os números das barras. Para cada barra, o campo com os números das barras é completamente percorrido. Para acelerar este processo, o subloop é encerrado assim que ocorre uma correspondência de números de barras. Sempre que existe uma correspondência, é adicionado um elemento ao campo com os números das linhas e o novo número é adicionado (k é o índice para os números das linhas encontradas).

Para que o nó inicial da linha ou da barra seja encontrado, é necessária mais uma função. Esta função deve percorrer as linhas e ler o nó inicial para verificar se existe correspondência com os números fornecidos. Uma vez que, os números dos nós são armazenados numa string, agora é necessária uma função que converta a string num campo de números.

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

Esta função percorre a string e examina cada caractere. Se o caractere contiver um número ou mais, eles são armazenados até que o final ou outro caractere seja alcançado. Quando um hífen é alcançado, uma série/faixa de números é reconhecida e os números intermediários são gerados automaticamente.

A função atual para extrair o ponto inicial de uma linha pode agora ser criada e torna-se bastante clara.

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

Novamente, há dois loops, como na função getLineNosByMemberNos. Desta vez, a ordem é de grande importância, caso contrário, a atribuição dos nós às linhas será perdida. O loop externo percorre os números das linhas e, se houver uma correspondência dentro do loop interno com uma linha, é utilizada a função strToIntArr para extrair os números dos nós, dos quais o primeiro é usado aqui.

O processo completo para obter os nós iniciais é então como segue. Primeiro, são obtidos os números das linhas das barras com os números de barras correspondentes, seguindo-se os nós de início das linhas.

    ' 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)

Resumo e Perspectiva

A função getLineNosByMemberNos forma a base para outras funções de seleção, assim como a função getLineStartNodeNosByLineNos. Utilizando este padrão, por exemplo, também é possível encontrar cargas para barras. As funções strToIntArr e intArrToStr estão disponíveis como ferramentas para ajudar a converter a seleção baseada em strings do RFEM em campos numéricos.

Outra possibilidade é a seleção por coordenadas. Por exemplo, pode ser especificado um espaço definido e todos os elementos dentro deste espaço serão selecionados. Esta forma de seleção será descrita em um artigo posterior.


Autor

O Eng. Günthel opera na área do apoio técnico para clientes.

Ligações
Downloads


;