Selection by Comment
The simplest one may be that comments were assigned during the creation of elements, which can then be searched for specifically. In the following text, an example of a function is shown that searches for members by their comment and returns the member numbers found:
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
The function has a loop over the transferred members, and if the string in "comment" and the comment of the member match, the member number is added to the integer field. Finally, the integer field with all member numbers is returned.
Selection of Member End Nodes
The selection of elements in the program and thus via the COM interface is carried out using strings. For a line, for example, the related nodes are transferred through a string in which the node numbers are separated by commas. The use of strings requires conversion into numerical values during programming, and vice versa. The following function, therefore, presents a way to convert the member numbers determined with the function above into a string. The member numbers are individually converted into characters using the CStr function, and after each number, a comma is added to the string. RFEM/RSTAB ignores the redundant comma at the end of the string, which can, therefore, remain.
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
This function now allows selection of the members filtered by comment via the COM interface.
' 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
Often, it is not enough to just select specific elements; subordinate elements are required. The following example shows how to find the start nodes of a member. Since this proves somewhat more difficult in RFEM than in RSTAB, because a line belongs to each member, this method was chosen.
First, one has to find the line numbers belonging to the members. The following function assumes that member numbers are already available and searches for the related line numbers.
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
This function has two nested loops. The main loop goes through the members and the subordinate loop through the member numbers. For each member, the field containing the member numbers is passed through completely. To speed up this process, the sub-loop is left as soon as the member numbers match. Every time there is a match, one element is added to the field containing the line numbers and the new number is added (k is the index for the found line numbers).
To find the start node of the line or member, another function is required. This function has to go through the lines and, if they match the given line numbers, read out the start node. Since the node numbers are stored in a string, a new function is needed to convert the string into a numerical field.
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
This function goes through the string and analyzes each character. If the character contains one or more numbers, they are collected until another character or the end is reached. When a hyphen is reached, a series/range of numbers is recognized and the numbers in between are generated automatically.
The actual function for extracting the start point of a line can now be created and is, therefore, very clear.
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
Again, there are two nested loops, as in the getLineNosByMemberNos function. This time, the sequence is very important because otherwise, the assignment of the nodes to the lines is lost. The outer loop cycles through the line numbers and, if a line within the inner loop is a match, the strToIntArr function is used to extract the node numbers, of which the first one is used here.
The entire procedure for getting the start nodes is then as follows. First, the line numbers of the members with the corresponding member numbers are fetched, followed by the line start nodes.
' 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)
Summary and Outlook
The getLineNosByMemberNos function is the basis for further selection functions, just as with the getLineStartNodeNosByLineNos function. Using this pattern, you can, for example, find loads for members. The strToIntArr and intArrToStr functions are also available as tools for converting the strings-based selection of RFEM into number fields.
Another option is selection via coordinates. For example, you can specify a defined space and select all elements within that space. This form of selection will be described in a future article.