Revit VB MACRO hints

I spent last saturday working on scripting with prof.Todesco; i publish something we've discovered and a macro. 

 

1_common problems

At first, to make a macro in vb language work, it is necessary to GENERATE it. So when you finish writing the procedure, it is mandatory to press the Generate button. MIND the fact that each .rvt file has his own .vb file, but unfortunatly the default name for both of them is the same ThisDocument.vb. Pay attention to what you're about to save or generate.

Unfortunatly, neither prof.Todesco understood what's the problem when the system encounther the "HANDLE FILE NOT FOUND" error. Stefano's procedure -macro:soluzioni ai problemi di avvio- is good indeed, but when the macro is getting complex, it make loose a part of our work.

 

2_how to recall paramethers

Since vb is basically another program which makes nothing more than a "dialogue" with revit, it is not possible to "call" revit's paramethers directly, without the mean of a new vb variable. Therefore, we need to create one new vb entity for each paramether we want to check, control or assign in the revit paramether.

 

Dim n as   =     create a new n, which is a

Integer     =     integer number 1   3    5  77   90

Double     =     real number, two figures after the comma 1,45 

Single=     real number, one figure after the comma 1,4 

 

(everything we want to create must be DIM-ensionate, with this imput)

 

Mind the fact that it is different to call Symbol (di Tipo) paramether and Instance paramether, thus we need different imputs.

 

Dim n as Integer

Dim fs As Symbols.FamilySymbol = Nothing

Dim param2 As Parameter = fs.ParametersMap("N")

param2.Set(n)

N is a symbol paramether in the revit family, whose correspondent in the vb file is n

 

Dim i as Integer

Dim fi As FamilyInstance

Dim param As Parameter = fi.ParametersMap("MARK")  

param.Set(i)

 MARK is an instance paramether in the revit family, whose correspondent in the vb file is i

 

We must work using vb entities only.

 

3_units 

Vb is a-dymensional, while Revit...well we know. For this reason the numbers we're using in the procedure has not their own unit: they don't use the customized configuration of each .rvt file, but the preconfigured combination which already exist in revit. Which mean that in vb were using DECIMAL FEET (the first unit we encounter in the units window....). We can either change the vb configuration (i don't actually know how) or we must convert each formula, with an appropriate coefficient.

centimeter to foot = 30,48

foot to centimeter = 1/30,48

foot to metre = 1/(30,48 x 100)

 

        

'convertitore cm/foot

Dim K As Double

K = 30.48

 

4_Forms: customization 

It is possible to customize a procedure: this mean that we can insert values according to the dimension/shape/option we want to obtain. In order to di this, we need to create a FORMTodesco was using forms each time he started executing a new macro, during the lesson.

At first we must create (and name) our form.

 

 

Next step consist in customizing the form (what does she has to ask), using the toolbar.

 

After that we need to set up the proprieties of each tool we inserted, with special attention to the NAME them. It is necessary to set up each object proprieties

A special attention to the form location. Todesco doesn't know why, but if we make Stefano-handle-not-valid procedure, we can't recall the form, we need to recreate it from the beginning.

 At last, we can write the scripting procedure:

 

 

'insert the form

Dim form As New RightForm

 

 ' i specify to show the form before executing the macro -mandatory

form.ShowDialog()


Dim n As Integer

'i collect the value i obtained thanks to the form

NumBox is the name i set in the form proprieties!!!! profConverso would have probably called it "paperoga"

'Text mean that the value to collect is the text

n = Val(form.NumBox.Text)

 
 
5_an Example
This macro is nothing more than a draft: without configuring the form, it won't work
 
 
    Public Sub gog_and_magog()


        'insert the form
        Dim form As New RightForm
        ' i specify to show the form before executing the macro -mandatory
        form.ShowDialog()

        Dim n As Integer
        'i give a name to the value i obtained using the form
        n = Val(form.NumBox.Text)


        'convertitore cm/inch
        Dim K As Double
        K = 30.48

        If (Not LoadFamily("RIGHT.rfa")) Then
            MsgBox("Loaded a family nono")
            Return
        End If

        Dim fs As Symbols.FamilySymbol = Nothing
        If (Not LoadFamilySymbol("RIGHT.rfa", "RIGHT", fs)) Then
            MsgBox("Non riesco a caricare il family symbol. ciao ciao")
            Return
        End If

        ' assegno un valore alla famiglia
        Dim param2 As Parameter = fs.ParametersMap("N")
        param2.Set(n)


        If (Not LoadFamily("devoto_board.rfa")) Then
            MsgBox("Loaded a family 2 nono")
            Return
        End If

        Dim fs2 As Symbols.FamilySymbol = Nothing
        If (Not LoadFamilySymbol("devoto_board.rfa", "devoto_board", fs2)) Then
            MsgBox("Non riesco a caricare il family symbol 2. ciao ciao")
            Return
        End If

        Dim fi2_pos As Geometry.XYZ = Application.Create.NewXYZ(0, 0, 0)

        Dim fi2 As FamilyInstance
        fi2 = Create.NewFamilyInstance(fi2_pos, fs2, Structural.Enums.StructuralType.NonStuctural)



        Dim phi As Double
        phi = 10

        Dim i As Integer

        Dim x As Double = 400 / K

        ' mettiamo quelli piccoli
        For i = 3 To n - 2

            Dim fi As FamilyInstance

            Dim y As Double = 0
            Dim z As Double = 0

            Dim p2 As Geometry.XYZ = Application.Create.NewXYZ(x, y, z)

            fi = Create.NewFamilyInstance(p2, fs, Structural.Enums.StructuralType.NonStuctural)

            ' assegno un valore all'istanza della famiglia
            Dim param As Parameter = fi.ParametersMap("MARK")
            param.Set(i)

            'Dim param3 As Parameter = fi.ParametersMap("THICKNESS")
            'Dim thickness As Double = param3.AsDouble()

            x = x - 18 / K

        Next

        x = 0

        ' mettiamo quelli grandi
        For i = 0 To 3

            ' j e' l'indice del montante: 0,1,2,n-1
            Dim j As Integer = i
            If i = 3 Then
                j = n - 1
            End If

            Dim fi As FamilyInstance

            Dim y As Double = 0
            Dim z As Double = 0

            Dim p2 As Geometry.XYZ = Application.Create.NewXYZ(x, y, z)

            fi = Create.NewFamilyInstance(p2, fs, Structural.Enums.StructuralType.NonStuctural)

            ' assegno un valore all'istanza della famiglia
            Dim param As Parameter = fi.ParametersMap("MARK")
            param.Set(j)

            'Dim p0 As Geometry.XYZ = Application.Create.NewXYZ(0.0, 0.0, 0.0)
            'Dim p1 As Geometry.XYZ = Application.Create.NewXYZ(0.0, 0.0, 1.0)

            'Dim line As Geometry.Line = Application.Create.NewLine(p0, p1, True)

            ' Rotate(fi, line, 20 * i)

            'Dim param3 As Parameter = fi.ParametersMap("THICKNESS")
            'Dim thickness As Double = param3.AsDouble()

            x = x + 18 / K

        Next


    End Sub

 

 

 

commenti

First of all it's right to say that your post is the best user manual for revit macros existing on web; I wrote because of a suspicion that some problems of those you have described could be resolved by using of macro for application; what about it? Finally, in order to deepen the structure of vb.net language, the following web site contains a good user manual.