1930x
001596
2019-10-23

通过 COM 接口选择单元的方法

Bei der Bearbeitung von Elementen über die COM-Schnittstelle stellt die Selektion von Elementen oft ein Problem dar, da sie nicht visuell über das Arbeitsfenster durchgeführt werden kann. Gerade bei Modellen, welche über die Programmoberfläche erzeugt wurden und dann über ein eigenes Programm modifiziert werden sollen, kann die Auswahl schwierig sein. Neben der Ausnahme, dass die Auswahl zuvor über RFEM getroffen wurde, gibt es mehrere Alternativen für die Programmierung.

注释选择

最简单的方法是在创建元素时分配注释,然后可以进行搜索。 下面是一个函数示例,该函数通过注释搜索杆件并返回找到的杆件编号:

函数getMemberNosByComment(members() As RFEM5.Member, comment As String) As Integer()
intArr ()设为整数
i变暗
j变暗
j = 0
ReDim intArr(00)
' 遍历杆件
对于i = 0UBound(杆件, 1)
如果(杆件(i).comment = 注释)
' 整数数组加1时的大小
ReDim Preserve intArr(0j)
intArr(j) = 杆件(i).no
j = j + 1
End If
下一个 i
' 返回整数数组
getMemberNosByComment = intArr
末端 功能

函数在传递的杆件上进行循环,如果“注释”中的字符串与杆件的注释匹配,则将杆件编号添加到整数字段中。 最后,返回包含所有杆件编号的整数字段。

杆件末端节点的选择

在程序中以及通过 COM 接口选择元素是通过字符串进行的。 以一条线为例,相关节点通过字符串传递,其中节点编号用逗号分隔。 使用字符串需要在编程过程中将其转换为数值,反之亦然。 下面的函数介绍了一种将用上面的函数确定的杆件编号转换为字符串的方法。 使用 CStr 函数将杆件编号单独转换为字符,并在每个编号后添加一个逗号。 RFEM/RSTAB 忽略字符串末尾的多余逗号,因此可以保留。

函数intArrToStr(intArr() As Integer) As String
将 str变暗字符串
i变暗
    
For i = 0 To UBound(intArr, 1)
str = str + CStr(intArr(i)) + ",
下一个 i
    
intArrToStr = str
末端 功能

现在使用该功能可以通过 COM 接口选择按注释过滤的杆件。

' 按注释选择杆件
Dim mems() As RFEM5.Member
mem_nos () 调暗整数
将 str变暗字符串
    
str = "测试注释"
mem_nos = getMemberNosByComment(mems, str)
    
iModelData.EnableSelections (True)
    
str = intArrToStr(mem_nos)
iModelData.SelectObjects 杆件对象,str

通常,仅仅选择特定的单元是不够的。需要从属元素。 下面的示例说明如何查找杆件的起始节点。 由于在RFEM中证明这比在RSTAB中困难一些,因为一条线属于每个杆件,所以选择了这种方法。

首先,要查找属于杆件的线编号。 下面的函数假设杆件编号已经可用,并搜索相关的线编号。

Function getLineNosByMemberNos(members() As RFEM5.Member, member_nos() As Integer) As Integer()
    
intArr ()设为整数
i变暗
j变暗
长度尺寸标注k
    
k = 0
ReDim intArr(00)
    
对于i = 0UBound(杆件, 1)
对于j = 0UBound(member_nos, 1)
如果(杆件(i).no = 杆件编号(j))
' 将数组大小增加1
ReDim Preserve intArr(0 To k)
intArr(k) = members(i).LineNo
k = k + 1
' 退出杆件编号上的循环
退出
End If
        
下一个 j
下一个 i
    
getLineNosByMemberNos = intArr
    
末端 功能

该函数有两个嵌套循环。 主回路通过杆件,从属回路通过杆件编号。 对于每个杆件,包含杆件编号的字段是完整的。 为了加快这个过程,只要杆件编号匹配,子回路就会退出。 每次匹配时,都会在包含线编号的字段中添加一个元素,并添加新的编号(k 是找到的线编号的索引)。

要查找线或杆件的起始节点,需要使用其他函数。 此功能必须遍历线,如果与给定的线编号相匹配,则读出起始节点。 由于节点编号是以字符串形式存储的,所以需要一个新的函数将字符串转换为数字字段。

函数strToIntArr(intList As String) As Integer()
' 可能的字符 "1-9 ; - ,
' 举例: 1-4,5;100 > 1,2,3,4,5,100
Dim ints() As Integer
tmpInts () 调暗整数
ReDim整数(0)
    
尺寸跨度布尔值
将 curInt变暗字符串
curInt = ""
将 i调暗整数
i = 0
将 j变暗整数
curChar调暗字符串
    
Do While (i < Len(intList))
curChar = Mid(intList, i + 1, 1)
        
' 如果字符串包含“-”,则表示跨度
If (curChar = "-") Then
        
跨度 = 真
tmpInts = 整数
ReDim Preserve tmpInts(0 To UBound(tmpInts, 1) + 1)
tmpInts(UBound(tmpInts, 1) - 1) = CInt(curInt)
整数 = tmpInts
curInt = ""
' 如果到达最后一个字符或者下一个字符是逗号或分号
ElseIf ((curChar = ",") 或 (curChar = ";") 或 (i = Len(intList) - 1))
        
' 到达最后一个字符,整数或跨度终止
如果(i = Len(intList) - 1)
curInt = curInt & curChar
End If
            
' 处理跨度
如果跨度那么
' 创建跨度之间的所有整数
firstNum调整整数
lastNum调暗整数
firstNum = ints(UBound(ints, 1) - 1)
lastNum = CInt(curInt)
curInt = ""
                
If (firstNum > lastNum)
将 tmp1整数
tmp1 = 上一个编号
最后一个编号 = 第一个编号
第一个编号 = tmp1
ints(UBound(ints, 1) - 1) = firstNum
                    
End If
                
' 扩展整数并将新的数字添加到数组中
tmpInts = 整数
ReDim保留tmpInts(0UBound(tmpInts, 1) + (lastNum - firstNum))
                
对于j = 0(lastNum - firstNum) - 1
tmpInts(UBound(ints, 1) + j) = j + firstNum + 1
下一个 j
                
整数 = tmpInts
跨度 = 假
            
' 添加新的数字
Else
'扩展整数并在整数上添加新的数字
tmpInts = 整数
ReDim Preserve tmpInts(0 To UBound(tmpInts, 1) + 1)
tmpInts(UBound(tmpInts, 1) - 1) = CInt(curInt)
整数 = tmpInts
curInt = ""
End If
        
Else
        
curInt = curInt & curChar
End If
    
i = i + 1
循环
    
' 数组的长度太长,所以被减小
ReDim保留ints(0 To UBound(ints, 1) - 1)
    
strToIntArr = 整数
末端 功能

这个函数会遍历整个字符串,并分析每个字符。 如果该字符包含一个或多个数字,则将一直收集到另一个字符或到达末尾。 当到达连字符时,会识别出一系列/范围的数字,并自动生成其间的数字。

现在可以创建实际的用于提取线的起点的功能,并且非常清晰。

函数getLineStartNodeNosByLineNos(lines() As RFEM5.RfLine, line_nos() As Integer) As Integer()
intArr ()设为整数
tmpIntArr () 调暗整数
将 str变暗字符串
i变暗
j变暗
长度尺寸标注k
    
k = 0
ReDim intArr(00)
    
For i = 0 To UBound(line_nos, 1)
对于j = 0UBound(lines, 1)
If (lines(j).no = line_nos(i))
' 将找到的线编号添加到数组中
ReDim Preserve intArr(0 To k)
str = lines(j).NodeList
tmpIntArr = strToIntArr(str)
intArr(k) = tmpIntArr(0)
k = k + 1
' 退出 line_nos_cpy 上的循环
退出
End If
        
下一个 j
下一个 i
    
getLineStartNodeNosByLineNos = intArr
末端 功能

这里有两个嵌套循环,例如在 getLineNosByMemberNos 函数中。 这时顺序就变得非常重要,否则就会丢失节点与线的分配。 外部循环遍历线的编号,如果内部循环中的一条线匹配,则使用strToIntArr函数提取节点编号,这里使用第一个。

获取起始节点的整个过程如下。 首先,获取杆件编号和杆件的线编号,然后是线的起始节点。

' 从杆件中选择起始节点
' 获取所有杆件的线编号
将 line_nos()变暗整数
line_nos = getLineNosByMemberNos(mems, mem_nos)
' 获取所有线的起始编号
stNodes_nos () 调暗整数
stNodes_nos = getLineStartNodeNosByLineNos(lines, line_nos)

总结和展望

与 getLineStartNodeNosByLineNos 一样,getLineNosByMemberNos 是进一步选择功能的基础。 使用该模式,例如可以查找杆件上的荷载。 strToIntArr 和 intArrToStr 函数也作为工具,用于将 RFEM 基于字符串的选择转换为数字域。

另一种方法是通过坐标选择。 例如,您可以指定一个已定义的空间并选择该空间内的所有单元。 这种选择方式将在后面的文章中介绍。


作者

Günthel 先生为Dlubal 软件客户提供技术支持。

链接
下载