Métodos para seleccionar elementos a través de la interfaz COM

Artículo técnico

Al editar elementos a través de la interfaz COM, a menudo la selección de elementos es un problema porque no se puede llevar a cabo visualmente por medio de la ventana de trabajo. La selección puede ser especialmente difícil para los modelos que se han creado mediante la interfaz del programa y después se van a modificar utilizando un programa por separado. Además de la excepción, cuando se ha realizado previamente la selección mediante RFEM, hay varias alternativas para programar.

Selección por comentario

El más simple puede ser que se hayan asignado los comentarios durante la creación de los elementos, que luego se pueden buscar específicamente. A continuación, se muestra un ejemplo de una función que busca las barras por su comentario y devuelve los números de barras encontrados:

Function getMemberNosByComment(members() As RFEM5.Member, comment As String) As Integer()
    Dim intArr() As Integer
    DimAs 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 función tiene un bucle sobre las barras transferidas y si coinciden la cadena en "comentario" y el comentario de la barra, el número de barra se agrega al campo numérico entero. Finalmente, se devuelve el campo numérico entero con todos los números de las barras.

Selección de los nudos del extremo de barra

La selección de elementos en el programa y de este modo también mediante la interfaz COM se lleva a cabo con la ayuda de cadenas. Para una línea, por ejemplo, los nudos relacionados se transfieren a través de una cadena cuyos números de nudo están separados por comas. El uso de cadenas necesita la conversión en valores numéricos durante la programación y viceversa. Por lo tanto, la siguiente función presenta una forma de convertir los números de barras determinados con la función anterior en una cadena. Los números de barras se convierten individualmente en caracteres usando la función CStr, y después de cada número, se agrega una coma la cadena. RFEM/RSTAB omite la coma redundante al final de la cadena, que por lo tanto puede permanecer.

Function intArrToStr(intArr() As Integer) As String
    Dim str As String
    DimAs Long
    
    For i = 0 To UBound(intArr, 1)
        str = str + CStr(intArr(i)) + ","
    Next i
    
    intArrToStr = str
End Function

Esta función ahora permite seleccionar las barras filtradas por comentario a través de la interfaz 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

A menudo no es suficiente seleccionar elementos específicos, sino que se requieren elementos subordinados. El siguiente ejemplo muestra la forma de encontrar los nudos iniciales de una barra. Dado que esto resulta algo más difícil en RFEM que en RSTAB, porque una línea pertenece a cada barra, se ha elegido de esta forma.

Primero, hay que encontrar los números de línea que pertenecen a las barras. La siguiente función asume que los números de barras ya están disponibles y busca los números de línea relacionados.

Function getLineNosByMemberNos(members() As RFEM5.Member, member_nos() As Integer) As Integer()
    
    Dim intArr() As Integer
    DimAs Long
    Dim j As Long
    DimAs 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 función tiene dos bucles anidados. El bucle principal recorre las barras y el bucle subordinado a través de los números de barras. Para cada barra, se pasa completamente el campo que contiene los números de barra. Para acelerar este proceso, el sub-bucle se deja tan pronto como coincidan los números de barras. Cada vez que hay una coincidencia, se añade un elemento al campo que contiene los números de línea y se agrega el nuevo número (k es el índice para los números de línea encontrados).

Para encontrar el nudo de inicio de la línea o barra, se requiere otra función. Esta función tiene que pasar por las líneas y, si coinciden con los números de línea dados, leer el nudo de inicio. Como los números de nudo se almacenan en una cadena, se necesita una nueva función para convertir la secuencia en un campo numérico.

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 = ""
    DimAs 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 función recorre la cadena y analiza cada carácter. Si el carácter es uno o más números, se recopilan hasta que se alcanza otro carácter o el final. Cuando se alcanza un guión, se reconoce una serie/intervalo de números y se generan automáticamente los números intermedios.

Ahora se puede crear la función real para extraer el punto inicial de una línea y, por lo tanto, está muy 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
    DimAs Long
    Dim j As Long
    DimAs 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

De nuevo, hay dos bucles anidados, como en la función getLineNosByMemberNos. Esta vez, la secuencia es muy importante porque, de lo contrario, se pierde la asignación de los nudos a las líneas. El bucle externo recorre los números de línea y, si una línea dentro del bucle interno es una coincidencia, la función strToIntArr se usa para extraer los números de nudo de los cuales se usa el primero aquí.

El procedimiento completo para obtener los nudos de inicio es el siguiente. En primer lugar, se recogen los números de línea de las barras con los números de barras correspondientes, seguidos por los nudos de inicio de línea.

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

Resumen y perspectiva

La función getLineNosByMemberNos es la base para otras funciones de selección, al igual que con la función getLineStartNodeNosByLineNos. Usando este patrón, puede, por ejemplo, encontrar cargas para las barras. Las funciones strToIntArr e intArrToStr también están disponibles como herramientas para convertir la selección basada en cadenas de RFEM en campos de número.

Otra opción es la selección por coordenadas. Por ejemplo, puede especificar un espacio definido y seleccionar todos los elementos dentro de ese espacio. Esta forma de selección se describirá en un artículo futuro.

Palabras clave

COM Selección

Descargas

Enlaces

Contacte con nosotros

Contacte con Dlubal Software

¿Tiene preguntas o necesita asesoramiento?
Contacte con nosotros a través de nuestro servicio de asistencia gratuito por correo electrónico, chat o fórum, o encuentre varias soluciones sugeridas y consejos útiles en nuestra página de preguntas más frecuentes (FAQ).

+34 911 438 160

info@dlubal.com

RFEM Programa principal
RFEM 5.xx

Programa principal

Software de ingeniería estructural de análisis por elementos finitos (AEF) para sistemas estructurales planos o espaciales compuestos de barras, placas, muros, láminas, sólidos y elementos de contacto

Precio de la primera licencia
3.540,00 USD
RFEM Otros
RF-COM 5.xx

Módulo adicional

Interfaz programable (API) basada en tecnología COM

Precio de la primera licencia
580,00 USD
RSTAB Programa principal
RSTAB 8.xx

Programa principal

El software de ingeniería estructural para el análisis y dimensionado de estructuras de barras, pórticos y entramados realizando cálculos lineales y no lineales de los esfuerzos internos, deformaciones y reacciones en los apoyos

Precio de la primera licencia
2.550,00 USD
RSTAB Otros
RS-COM 8.xx

Módulo adicional

Interfaz programable (API) basada en tecnología COM

Precio de la primera licencia
580,00 USD