Selección por comentario
La más sencilla es que al crear elementos se asignan comentarios, que luego se pueden buscar específicamente. A continuación se muestra un ejemplo de una función que busca barras según su comentario y devuelve los números de barra encontrados:
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)
' recorrer los miembros
For i = 0 To UBound(members, 1)
If (members(i).comment = comment) Then
' aumentar el tamaño del array entero en 1
ReDim Preserve intArr(0 To j)
intArr(j) = members(i).no
j = j + 1
End If
Next i
' devolver array de enteros
getMemberNosByComment = intArr
End Function
La función tiene un bucle sobre las barras pasadas y, cuando hay una coincidencia entre la cadena "comment" y el comentario de la barra, el número de barra se agrega al campo de enteros. Al final, el campo de enteros con todos los números de barra se devuelve.
Selección de nodos finales de barra
La selección de elementos en el programa y, por lo tanto, también a través de la interfaz COM, se realiza mediante el uso de cadenas. Por ejemplo, en una línea, los nodos asociados se pasan a través de una cadena en la que los números de nodo se almacenan separados por comas. El uso de cadenas requiere conversión a valores numéricos y viceversa en la programación. A continuación se presenta la función que puede convertir los números de barra obtenidos de la función anterior en una cadena. Los números de barra se convierten individualmente en caracteres mediante la función CStr y después de cada número se agrega una coma a la cadena. La coma innecesaria al final de la cadena es ignorada por RFEM/RSTAB y, por lo tanto, puede permanecer.
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
Con esta función ahora es posible seleccionar las barras filtradas por comentario a través de la interfaz COM.
' seleccionar barras por comentario
Dim mems() As RFEM5.Member
Dim mem_nos() As Integer
Dim str As String
str = "comentario de prueba"
mem_nos = getMemberNosByComment(mems, str)
iModelData.EnableSelections (True)
str = intArrToStr(mem_nos)
iModelData.SelectObjects MemberObject, str
A menudo no basta con la selección de ciertos elementos, sino que se necesitan elementos subordinados. A continuación, se muestra un ejemplo de cómo se puede encontrar los nodos iniciales de una barra. Como el proceso en RFEM es algo más complicado que en RSTAB, ya que aquí cada barra también pertenece a una línea, se ha elegido este camino.
Primero se deben encontrar los números de línea para las barras. La siguiente función asume que ya se tienen los números de barra y busca los números de línea correspondientes.
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
' aumentar tamaño del array en 1
ReDim Preserve intArr(0 To k)
intArr(k) = members(i).LineNo
k = k + 1
' salir del bucle sobre member_nos
Exit For
End If
Next j
Next i
getLineNosByMemberNos = intArr
End Function
Esta función tiene dos bucles anidados. La bucle principal recorre las barras y la bucle secundaria recorre los números de barra. En cada barra, el campo con los números de barra se recorre completamente. Para acelerar este proceso, se abandona el bucle secundario tan pronto como se encuentra una coincidencia de números de barra. En caso de coincidencia, el campo con los números de línea se alarga cada vez un elemento y se agrega el nuevo número (k es el índice para los números de línea encontrados).
Para encontrar el nodo inicial de la línea o barra, se necesita otra función. Esta función debe recorrer las líneas y, en caso de coincidencia con los números de línea dados, leer el nodo inicial. Dado que los números de nodo se almacenan en una cadena, ahora se necesita una función que convierta la cadena en un campo de números.
Function strToIntArr(intList As String) As Integer()
' caracteres posibles "1-9 ; - ,"
' ejemplo: 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)
' si la cadena contiene "-" se nota un rango
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 = ""
' si se alcanza el último carácter o la siguiente es una coma o punto y coma
ElseIf ((curChar = ",") Or (curChar = ";") Or (i = Len(intList) - 1)) Then
' se alcanza el último carácter, se termina entero o rango
If (i = Len(intList) - 1) Then
curInt = curInt & curChar
End If
' tratar el rango
If span Then
' crear todos los enteros entre el rango
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
' extender ints y agregar nuevos números al 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
' añadir nuevo dígito
Else
'extender ints y agregar nuevo número a int
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
' el array es un elemento demasiado largo y se reduce
ReDim Preserve ints(0 To UBound(ints, 1) - 1)
strToIntArr = ints
End Function
Esta función recorre la cadena y examina cada carácter. Si es un número o varios, estos se recogen hasta que se alcanza el final o se encuentra otro carácter. Cuando se alcanza un guion, se reconoce una serie/rango de números y los números intermedios se generan automáticamente.
La función real para extraer el punto de inicio de una línea se puede crear ahora y resulta así 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
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
' añadir número de línea encontrado al array
ReDim Preserve intArr(0 To k)
str = lines(j).NodeList
tmpIntArr = strToIntArr(str)
intArr(k) = tmpIntArr(0)
k = k + 1
' salir del bucle sobre line_nos_cpy
Exit For
End If
Next j
Next i
getLineStartNodeNosByLineNos = intArr
End Function
Aquí también hay dos bucles anidados, como en la función getLineNosByMemberNos. Esta vez, el orden es de gran importancia, ya que de otro modo se perdería la asignación de nodos a líneas. El bucle exterior recorre los números de línea y, cuando en el bucle interior se encuentra una coincidencia con una línea, los números de nodo se extraen usando la función strToIntArr, usando aquí el primero.
El flujo completo para encontrar los nodos de inicio se ve entonces como sigue. Primero se obtienen los números de línea de las barras con los números de barra correspondientes y luego los nodos iniciales de línea.
' seleccionar nodos iniciales de las barras
' obtener números de línea de todas las barras
Dim line_nos() As Integer
line_nos = getLineNosByMemberNos(mems, mem_nos)
' obtener números de inicio de todas las líneas
Dim stNodes_nos() As Integer
stNodes_nos = getLineStartNodeNosByLineNos(lines, line_nos)
Resumen y perspectiva
La función getLineNosByMemberNos forma la base para otras funciones de selección así como para la función getLineStartNodeNosByLineNos. Usando este patrón, es posible, por ejemplo, encontrar también cargas relacionadas con barras. Se dispone de las funciones strToIntArr e intArrToStr como herramientas que permiten convertir la selección basada en cadenas de RFEM en campos numéricos.
Otra posibilidad es la selección por coordenadas. Por ejemplo, se puede definir un espacio y todos los elementos dentro de este espacio son seleccionados. Esta forma de selección se describirá en un artículo posterior.