2026x
001596
2019-10-23

Metody wyboru elementów poprzez interfejs 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.

Wybór według komentarza

Najprostszym może być to, że komentarze zostały nadane podczas tworzenia elementów, które można następnie wyszukać. Poniżej znajduje się przykład funkcji, która wyszukuje pręty według ich komentarza i zwraca znalezione numery prętów:

Funkcja getMemberNosByComment(members() As RFEM5.Member, komentarz As String) As Integer()
Dim intArr() As Integer
Dim i As Long
wym j jak
j = 0
ReDim intArr(0 do 0)
' pętla nad prętami
For i = 0 To UBound(pręty, 1)
Jeżeli (pręty(i).komentarz = komentarz) Wtedy
' rozmiar, jeśli tablica liczb całkowitych jest zwiększona o 1
Zmniejsz Wymiar Zachowaj intArr (0 do j)
intArr(j) = pręty(i).no
j = j + 1
End If
Następny i
' return tablica liczb całkowitych
getMemberNosByComment = intArr
Koniec Funkcja

Funkcja wykonuje pętlę nad przenoszonymi prętami, a jeśli ciąg znaków w "comment" i komentarzu dla pręta są zgodne, numer pręta jest dodawany do pola typu integer. Na koniec zwracane jest pole całkowite ze wszystkimi numerami prętów.

Wybór węzłów końcowych pręta

Wybór elementów w programie, a tym samym poprzez interfejs COM, odbywa się za pomocą ciągów znaków. Na przykład w przypadku linii odpowiednie węzły są przenoszone za pomocą ciągu znaków, w którym numery węzłów są oddzielone przecinkami. Użycie ciągów znaków wymaga konwersji na wartości liczbowe podczas programowania i odwrotnie. Poniższa funkcja przedstawia sposób zamiany liczb prętów określonych za pomocą powyższej funkcji na łańcuch znaków. Liczby prętów są indywidualnie konwertowane na znaki przy użyciu funkcji CStr, a po każdej liczbie dodawany jest przecinek. Program RFEM/RSTAB ignoruje nadmiarowy przecinek na końcu ciągu znaków, który może zatem pozostać.

Funkcja 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)) + ","
Następny i
    
intArrToStr = str
Koniec Funkcja

Ta funkcja umożliwia teraz wybór prętów filtrowanych według komentarza za pośrednictwem interfejsu COM.

' wybierz pręty według komentarza
Dim mems() Jako RFEM5.Pręt
Dim mem_nos() As Integer
Dim str As String
    
str = "komentarz testowy"
mem_nos = getMemberNosByComment(mems, str)
    
iModelData.EnableSelections (True)
    
str = intArrToStr(mem_nos)
iModelData.SelectObjects MemberObject, str

Często nie wystarczy wybrać tylko określone elementy; elementy podrzędne są wymagane. Poniższy przykład pokazuje, jak znaleźć węzły początkowe pręta. Wybrano tę metodę, ponieważ w programie RFEM jest to nieco trudniejsze niż w RSTAB, ponieważ do każdego pręta należy linia.

Najpierw należy znaleźć numery linii należących do prętów. Poniższa funkcja zakłada, że numery prętów są już dostępne, i wyszukuje powiązane numery linii.

Funkcja getLineNosByMemberNos(members() As RFEM5.Member, member_nos() As Integer) As Integer()
    
Dim intArr() As Integer
Dim i As Long
wym j jak
Dim k As Long
    
k = 0
ReDim intArr(0 do 0)
    
For i = 0 To UBound(pręty, 1)
Dla j = 0 To UBound(member_nos, 1)
Jeżeli (pręty(i).no = pręty(j)) Wtedy
' zwiększ rozmiar tablicy o 1
ReDim Zachowaj intArr(0 To k)
intArr(k) = pręty(i).LineNo
k = k + 1
' wyjście z pętli nad prętami_nos
Wyjście dla
End If
        
Następny j
Następny i
    
getLineNosByMemberNos = intArr
    
Koniec Funkcja

Ta funkcja ma dwie zagnieżdżone pętle. Pętla główna przechodzi przez pręty, a pętla podrzędna przez numery prętów. Dla każdego pręta pole zawierające numery prętów jest całkowicie przeszukiwane. Aby przyspieszyć ten proces, podpętla jest opuszczana, gdy tylko numery prętów są zgodne. Za każdym razem, gdy występuje dopasowanie, do pola z numerami wierszy dodawany jest jeden element i dodawany jest nowy numer (k jest indeksem znalezionych numerów wierszy).

Aby znaleźć węzeł początkowy prostej lub pręta, wymagana jest inna funkcja. Funkcja ta musi przejść przez linie i jeśli pasują do podanych numerów linii, odczytać węzeł początkowy. Ponieważ numery węzłów są przechowywane w ciągu znaków, potrzebna jest nowa funkcja, która przekształci ciąg w pole liczbowe.

Function strToIntArr(intList As String) As Integer()
' możliwe znaki "1-9 ; - ,"
' przykład: 1-4,5;100 > 1,2,3,4,5,100
Dim ints() As Integer
Dim tmpInts() As Integer
Wymiar (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)
        
' jeśli łańcuch zawiera "-", to jest zapisywany span
Jeżeli (curChar = "-") Wtedy
        
rozpiętość = Prawda
tmpInts = ints
ReDim Preserve tmpInts(0 To UBound(tmpInts, 1) + 1)
tmpInts(UBound(tmpInts, 1) - 1) = CInt(curInt)
ints = tmpInts
curInt = ""
' jeśli został osiągnięty ostatni znak lub następnym znakiem jest przecinek lub średnik
ElseIf ((curChar = ",") Or (curChar = ";") Or (i = Len(intList) - 1)) Wtedy
        
' Osiągnięto ostatni znak, liczba całkowita lub zakres są zakończone
Jeżeli (i = Len(intList) - 1) Wtedy
curInt = curInt & curChar
End If
            
' potraktuj przęsło
Jeżeli rozpiętość Wtedy
' utwórz wszystkie liczby całkowite między elementami przęsłowymi
Dim firstNum As Integer
Dim lastNum As Integer
firstNum = ints(UBound(ints, 1) - 1)
lastNum = CInt(curInt)
curInt = ""
                
Jeżeli (firstNum > lastNum) Wtedy
Dim tmp1 As Integer
tmp1 = lastNum
lastNum = firstNum
pierwszaNum = tmp1
ints(UBound(ints, 1) - 1) = firstNum
                    
End If
                
' rozszerz ints i dodaj nowe liczby do tablicy
tmpInts = ints
ReDim Zachowaj tmpInts(0 To UBound(tmpInts, 1) + (lastNum - firstNum))
                
Dla j = 0 To (lastNum - firstNum) - 1
tmpInts(UBound(ints, 1) + j) = j + firstNum + 1
Następny j
                
ints = tmpInts
rozpiętość = Fałsz
            
' dodaj nową cyfrę
Else
'rozszerz cale i dodaj nową liczbę do cale
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
Pętla
    
' tablica jest o jeden element za długa i jest zmniejszana
ReDim Zachowaj ints(0 do UBound(ints, 1) - 1)
    
strToIntArr = cale
Koniec Funkcja

Ta funkcja przechodzi przez łańcuch i analizuje każdy znak. Jeżeli znak zawiera jedną lub więcej cyfr, są one zbierane aż do osiągnięcia kolejnego znaku lub końca. Po osiągnięciu łącznika rozpoznawany jest ciąg/zakres liczb, a liczby pomiędzy nimi są generowane automatycznie.

Teraz można utworzyć funkcję wyodrębniania punktu początkowego prostej, dzięki czemu jest bardzo przejrzysta.

Funkcja 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
wym j jak
Dim k As Long
    
k = 0
ReDim intArr(0 do 0)
    
For i = 0 To UBound(line_nos, 1)
Dla j = 0 To UBound(linie, 1)
Jeżeli (lines(j).no = line_nos(i)) Wtedy
' dodaj znaleziony numer wiersza do tablicy
ReDim Zachowaj intArr(0 To k)
str = lines(j).NodeList
tmpIntArr = strToIntArr(str)
intArr(k) = tmpIntArr(0)
k = k + 1
' wyjście z pętli przez line_nos_cpy
Wyjście dla
End If
        
Następny j
Następny i
    
getLineStartNodeNosByLineNos = intArr
Koniec Funkcja

Znowu istnieją dwie zagnieżdżone pętle, jak w funkcji getLineNosByMemberNos. Tym razem kolejność jest bardzo ważna, ponieważ w przeciwnym razie przypisanie węzłów do linii zostanie utracone. Zewnętrzna pętla przechodzi przez numery linii, a jeśli linia w wewnętrznej pętli jest dopasowana, funkcja strToIntArr jest używana do wyodrębnienia numerów węzłów, z których pierwszy jest używany w tym miejscu.

Cała procedura uzyskiwania węzłów początkowych przebiega następująco. Najpierw pobierane są numery linii prętów o odpowiadających im numerach prętów, a następnie węzły początkowe linii.

' wybierz węzły początkowe z prętów
' pobierz numery linii ze wszystkich prętów
Dim line_nos() As Integer
line_nos = getLineNosByMemberNos(mems, mem_nos)
' pobierz numery początkowe ze wszystkich wierszy
Dim stNodes_nos() jako liczba całkowita
stNodes_nos = getLineStartNodeNosByLineNos(lines, line_nos)

Podsumowanie i potencjał rozwoju

Funkcja getLineNosByMemberNos, podobnie jak funkcja getLineStartNodeNosByLineNos, stanowi podstawę dla dalszych funkcji wyboru. Za pomocą tego wzorca można na przykład znaleźć obciążenia dla prętów. Funkcje strToIntArr i intArrToStr są również dostępne jako narzędzia do konwersji wyboru w programie RFEM opartego na ciągach znaków w pola liczbowe.

Inną opcją jest wybór poprzez współrzędne. Można na przykład określić zdefiniowaną przestrzeń i wybrać wszystkie elementy w tej przestrzeni. Ta forma wyboru zostanie opisana w następnym artykule.


Autor

Pan Günthel zapewnia wsparcie techniczne klientom firmy Dlubal Software i zajmuje się ich zapytaniami.

Odnośniki
Pobrane


;