niedziela, października 16, 2011

Makro w VSTA cz.I

Na dobry początek zacznijmy od podstaw…
Każdy wprawiony SOLIDWORKS-owiec nagrywał makro. Nie każdy jednak pisał makro w języku VB.NET. Większość zapisuje makro w formacie *.swp i edytuje je w VBA, czyli w języku Visual Basic for Application. W tym materiale przedstawię inne podejście: zapis makra do *.vbproj i edycja w Visual Studio Tools for Application (VSTA).
Według mnie, jest to najlepsza metoda uczenia się programowania SW dla osób początkujących, które chcą rozpocząć fascynującą przygodę z kodem SOLIDWORKSa tzn. nagrywamy makro, patrzymy co się zapisało a następnie edytujemy je.
Zacznijmy od napisania prostego makra w VB.NET, służącego do pomiaru zaznaczonych na modelu powierzchni. Nagramy makro, zapiszemy je, zmodyfikujemy a następnie uruchomimy w SW.
Jak nagrać makro?
  1. Otwórz model części.
  2. Ważne, żeby przed nagrywaniem zastanowić się co chcemy osiągnąć, co chcemy nagrać i już podczas samego nagrywania, nie wykonywać niepotrzebnych rzeczy np. nie obracaj modelem, nie przybliżaj go itp. Jeżeli masz coś zaznaczonego, na modelu, w drzewie to odznacz to.
    Teraz możesz uruchomić nagrywanie makra klikając przycisk „Rejestruj\Wstrzymuj makro" tut1 1 z paska narzędziowego „Makro” tut1 2.
  3. Zaznacz dwie powierzchnie (którekolwiek) a następnie...
  4. Zmierz zaznaczone powierzchnie tzn. wybierz funkcję „Zmierz” z menu głównego „Narzędzia”.

    tut1 3
  5. Wyłącz funkcję „Zmierz”.
    1. Zakończ nagrywanie makra klikając tut1 4 z paska narzędziowego „Makro” tut1 5.
    2. Zapisz makro w formacie *.vbproj na dysku.
    tut1 6
    Na dysku została zapisana cała struktura projektu, którą teraz możesz otworzyć klikając na plik z rozszerzeniem *.snl (SwMacro.snl). Projekt zostanie otwarty w SW VSTA (SOLIDWORKS Visual Studio Tools for Applications) . Wszystkie pliki projektu możemy zobaczyć w oknie Project Explorer.
    tut1 7
    Nasze makro zostało zapisane w pliku SolidWorksMacro.vb. Edytując zawartość pliku SolidWorksMacro.vb modyfikujemy nasze makro – nasz program.
    Zobaczmy co zostało zapisane.
    Imports SolidWorks.Interop.sldworks
    Imports SolidWorks.Interop.swconst
    Imports System
    Partial Class SolidWorksMacro
    Public Sub main()
    Dim swDoc As ModelDoc2 = Nothing
    Dim swPart As PartDoc = Nothing
    Dim swDrawing As DrawingDoc = Nothing
    Dim swAssembly As AssemblyDoc = Nothing
    Dim boolstatus As Boolean = false
    Dim longstatus As Integer = 0
    Dim longwarnings As Integer = 0
    swDoc = CType(swApp.ActiveDoc,ModelDoc2)
    boolstatus = swDoc.Extension.SelectByID2("", "FACE", 0.08143433284965,
    0.01851879019517, -0.06799999999998, false, 0, Nothing, 0)
    boolstatus = swDoc.Extension.SelectByID2("", "FACE", 0.06099499409754,
    0.01562159853449, -0.04957751137664, true, 0, Nothing, 0)
    End Sub
    ''' <summary>
    ''' The SldWorks swApp variable is pre-assigned for you.
    ''' </summary>
    Public swApp As SldWorks
    End Class
    Wniosek 1. Kod w VB.NET różni się od kodu VBA. Oczywista sprawa.
    Wniosek 2. Nie wszystko się nagrało. W naszym przypadku nie nagrała się funkcja „Zmierz”, a przecież z poziomu API możemy z niej skorzystać! Niestety, ale tak już jest z nagrywaniem makr. Będziemy musieli sobie radzić. Pocieszeniem może być to, że jak zrobicie kilka fajnych programów to już nie będziecie musieli nagrywać makr. Wystarczy wam plik pomocy API - apihelp.chm. Znajdziecie go w …\SolidWorks Corp\SolidWorks\api\apihelp.chm
    tut1 8
    Krok po kroku przeanalizujmy zapisany kod w pliku SolidWorksMacro.vb.
    Na samej górze mamy:
    Imports SolidWorks.Interop.sldworks
    Imports SolidWorks.Interop.swconst
    Imports System
    Wpisanie tych wierszy powoduje, iż w dalszej części kodu możemy używać klas z przestrzeni nazw SolidWorks.Interop.sldworks, SolidWorks.Interop.swconst, System bez podawania nazw w pełni kwalifikowanych - tzn. gdybyśmy wykasowali te trzy linijki kodu to np. zamiast linii kodu
    Dim swDoc As ModelDoc2 = Nothing
    musielibyśmy napisać
    Dim swDoc As SolidWorks.Interop.sldworks.ModelDoc2 = Nothing
    Przestrzeń nazw może być rozumiana jako pojemnik na klasy - podobnie jak pliki w folderach. Umieszczając klasy w przestrzeni nazw, możemy grupować je i w ten sposób uniknąć kolizji nazw. Może jeszcze inaczej. Jeżeli w firmie A zdefiniowana została klasa o nazwa „coś” i w firmie B istniałaby klasa o takiej samej nazwie, to gdyby nie istniał mechanizm przestrzeni nazw, kompilator nie mógłby określić, do której nazwy odwołuje się aplikacja. Najważniejsze jest to, że dzięki instrukcji Imports możemy uniknąć wpisywania nazw kwalifikowanych co sprawia, iż kod jest czytelniejszy.
    Najważniejsza część naszego kodu zawarta jest właśnie w klasie, czyli między linią kodu
    Partial Class SolidWorksMacro
    a
    End Class
    Klasa zawiera deklarację oraz implementację zmiennych, metod, właściwości oraz zdarzeń.
    Nasza klasa SolidWorksMacro w tym momencie zawiera procedurę main() oraz deklarację zmiennej globalnej (czyli takiej, która istnieje w całej aplikacji) swApp. Pierwsze linijki kodu publicznej (Public) procedury main() to deklaracja zmiennych lokalnych.
    Dim swDoc As ModelDoc2 = Nothing
    Dim swPart As PartDoc = Nothing
    Dim swDrawing As DrawingDoc = Nothing
    Dim swAssembly As AssemblyDoc = Nothing
    Dim boolstatus As Boolean = false
    Dim longstatus As Integer = 0
    Dim longwarnings As Integer = 0
    Najprościej ujmując, swDoc typu ModelDoc2 to document program SolidWorks - swApp. W zależności jaki dokument w SOLIDWORKSie będzie aktywny (swDoc = CType(swApp.ActiveDoc,ModelDoc2))to taki obiekt będzie przypisany do zmiennej swDoc.
    W tym momencie uzupełnimy kod procedury głównej.
    Public Sub main()
    swDoc = CType(swApp.ActiveDoc, ModelDoc2)
    If
    swDoc Is Nothing Then Exit Sub
    If swDoc.GetType = 1 Then
    swPart = swDoc
    ElseIf swDoc.GetType = 2 Then
    swAssembly = swDoc
    Exit Sub
    ElseIf swDoc.GetType = 3 Then
    Exit Sub
    End If
    'Zaznaczenie i pomiar powierzchni
    Dim selCount As Long = 0
    Dim swselMgr As SelectionMgr = swDoc.SelectionManager
    Dim selType As swSelectType_e
    Dim selObject As Object
    Dim swFace As Face2 = Nothing
    Dim value As Double = 0.0
    selCount = swselMgr.GetSelectedObjectCount()
    If Not selCount = 0 Then

    For i As Integer = 1 To selCount
    selType = swselMgr.GetSelectedObjectType2(i)
    If selType = swSelectType_e.swSelFACES Then
    selObject = swselMgr.GetSelectedObject2(i)
    swFace = selObject
    value += swFace.GetArea
    End If
    Next
    MsgBox("Wartość zaznaczenia = " & Math.Round(value * 1000000, 2) & " mm^2")
    Else
    End If

    End Sub
    Dopisaliśmy instrukcję warunkową, która w sytuacji, gdy nie ma aktywnego modelu kończy procedurę:
    If swDoc Is Nothing Then Exit Sub
    oraz instrukcję warunkową, która sprawdza typ aktywnego dokumentu (funkcja GetType) i przypisuje go do odpowiedniej zmiennej.
    Wyrzuciliśmy fragment kodu, który odpowiedzialny był za zaznaczenie dwóch powierzchni a następnie zastąpiliśmy innym, który spełni nasze oczekiwania. Zostanie on opisany w drugiej części tutoriala. W drugiej części również jak skompilować program, jak podpiąć plik dll do SOLIDWORKSa oraz wiele innych aspektów.


    Copyright © ADKSolid. All rights reserved

    Brak komentarzy:

    Prześlij komentarz