excel vba to drive inventor

excel vba to drive inventor

Anonymous
Not applicable
8,658 Views
10 Replies
Message 1 of 11

excel vba to drive inventor

Anonymous
Not applicable

Hello everyone,

I am new to this forum as a member however I have used the knowledge shared in this forum to learn about ilogic. I’ve been learning ilogic for about a year now and still learning. I have done some automation with ilogic but now I am starting to dive in to learning vba to automate inventor. I am currently trying to put together an excel vba that would let me browse for an inventor part file open it and read parameters from a specified sheet of that excel. Is it possible to match the name user parameters from the part file to the name on the excel sheet column then get the values from the column next to it with a loop method.  Please forgive me if this confusing.  Thank you very much.

 

Sincerely

Adam T.

0 Likes
Accepted solutions (1)
8,659 Views
10 Replies
Replies (10)
Message 2 of 11

Anonymous
Not applicable

adetes3,

 

If I understand your situation correctly, you have an Excel worksheet filled out similarly to the image below:

 

 

excel.JPG

 

I came up with a code which would loop through each file, get the properties listed in B1:D1 and place their values in their

corresponding cells. The code isn't very robust, so if you have iProperties in areas other than "Design Tracking Properties",

it won't work properly. Hope this gives you a decent start. Let me know if you have any questions on the code.

 

 

Sub GetProperties()

Dim oWkbk As Workbook
Set oWkbk = ThisWorkbook

Dim oSheet As Worksheet
Set oSheet = oWkbk.ActiveSheet

' Define range where properties are
sPropRange = "B1:D1"
' Define range of filepaths
sFilepathRange = "A2:A2"

Dim oPropNames As Collection
Set oPropNames = New Collection

' Add property names to collection
For Each oCell In oSheet.Range(sPropRange)
    oPropNames.Add (oCell.Value)
Next oCell

' Get new instance of Inventor
Dim oInvApp As Inventor.Application
Set oInvApp = CreateObject("Inventor.Application")

Dim invSummaryInfo As PropertySet
Dim oDoc As Inventor.Document
Dim sFilePath As String

' Loop through files
For Each oCell In oSheet.Range(sFilepathRange)

    ' Open file invisibly
    Set oDoc = oInvApp.Documents.Open(oCell, False)
    ' Get design tracking properties of document
    Set invSummaryInfo = oDoc.PropertySets.Item("Design Tracking Properties")
    i = 1
    ' For each property, get value and place in corresponding cell
    For Each oItem In oPropNames
        
        oCell.Offset(0, i).Value = invSummaryInfo.Item(CStr(oItem)).Value
        i = i + 1
        
    Next oItem
    ' Close document and move onto next
    oDoc.Close
Next oCell

Set oInvApp = Nothing

End Sub

 

0 Likes
Message 3 of 11

Anonymous
Not applicable

foxrid3r,

 

Thanks for taking the time to help. I just reread my post and it was confusing, so let me see if I can describe it better here. Shown below is an image example of the excel set up I have with inputs and inventor sheet. The “inventor” sheet is set up with 3 columns; parameter name, value, and units. What I was trying to do was to write a vba inside the excel that allows user to browse for inventor file (part or assembly) as shown on the image the inventor file will have user parameters with the same name as shown in the “inventor” sheet, so once the user finds and opens the file the code would compare the parameter name from the excel to the one in the inventor file and if they are same copy the value and unit to the inventor file and loop for each parameter. Sorry I haven't gone through your code yet, I just want to reexplain my post. Would this be easier in reverse where the code will be inside inventor file then look for excel with the same parameter name...?

 

excel_vba_inv.GIF

 

 

Sincerely,

Adam T.

0 Likes
Message 4 of 11

Anonymous
Not applicable

adetes3,

 

Okay, I think I understand what you are trying to do now. You want to browse (much like File->Open) for a part/assembly, if that part/assembly has parameters that match the names in Excel, then copy the values inside Excel to the corresponding part/assembly parameters. Is that accurate?

 

You could write this for use within the Inventor API or Excel API, it just depends on how you want the end user to interface with the parts/assemblies. You have to ask yourself one important question which will govern whether you create the VBA script for use inside of Excel or Inventor--"Do I want to update the parameters of numerous files quickly and efficiently using a master Excel spreadsheet or do I want to open the part/assembly within Inventor and then browse for the Excel file to update my parameters?"

 

If you're trying to update a lot of files in a short amount of time then I would choose to write the code for use inside of Excel in which you would fill out your "inputs" sheet, run the script, browse for file, let code update file if applicable, change your inputs, browse for a different file, let the code update that file, and so on. You wouldn't have to even see the file being opened which could allow for very fast performance.

 

If you're design flow is to create a new part/assembly from a template, which had generic values for the desired parameters, and then update those parameters using your Excel spreadsheet (in which you would edit before running the code) then I would write the code for use within Inventor.

 

Once you've figured out how you want the user to interact with the part/assembly and what performance you'd like, then you'll know which route to take. Let me know and we can try to figure something out.

 

 

Regards,

Trevor

0 Likes
Message 5 of 11

Anonymous
Not applicable

Trevor,

Your understanding is accurate. I started out with thinking to do it from within excel API but I think it would be best for me if I do it within the inventor, in which the user open an inventor part file named "drive" then they would run the macro via a button or manual, which will prompt them to browse the excel file and so on. I really appreciate it if you could help me figure this out. Thank you very much for taking the time. 

 

Sincerely,

 

Adam

0 Likes
Message 6 of 11

Anonymous
Not applicable
Accepted solution

Adam,

 

Here is what I came up with. You'll have to modify it slightly to suit your needs, but it should be a good start. I should note that you will have to add a reference to the Excel library in order to use functions/classes native to Excel. To do this, open the VBA editor in Inventor, go to Tools>References and check the box for "Microsoft Excel XX.0 Object Library". Let me know if you run into any trouble.

 

Here is the Excel file I was working with:

Capture.JPG

 

Sub GetProperties()
Dim oApp As Application
Set oApp = ThisApplication

Dim oDoc As Document
Set oDoc = oApp.ActiveDocument

' Check if user is in part or assembly
If oDoc Is Nothing Or TypeOf oDoc Is DrawingDocument Then
    Exit Sub
End If

Dim oCompDef As ComponentDefinition
' Get component definition
Set oCompDef = oDoc.ComponentDefinition

Dim oParams As Parameters
Dim oParam As Parameter
' Get paramters object
Set oParams = oCompDef.Parameters

Dim oExcel As Excel.Application
' Create Excel object
Set oExcel = CreateObject("Excel.Application")

' Define sheet name where information resides
Dim sSheetName As String
sSheetName = "inventor"
Dim sFilePath

' Prompt user to select Excel file to read from
' Alternatively, you could hard code the filepath like this:
' sFilePath = "C:/ExcelFile.xlsx"
sFilePath = oExcel.GetOpenFilename(FileFilter:="Excel Files (*.xls*),*.xls*", Title:="Select Excel File to Read From")
Dim oWkbk As Workbook
' Open Excel file invisibly
If sFilePath = False Then
    Exit Sub
Else
    Set oWkbk = oExcel.Workbooks.Open(sFilePath, False)
End If

Dim oSheet As WorkSheet
' Get specified sheet
Set oSheet = oWkbk.Sheets(sSheetName)

' Set range where parameter names reside in sheet
Dim sParamRange As String
sParamRange = "A2:A6"

Dim oCell As Range
' Loop through each parameter listed in sheet
For Each oCell In oSheet.Range(sParamRange)
    ' Parse through parameters and check to see if parameter name matches current parameter from Excel
    For Each oParam In oParams
        ' If names match, copy value and units from Excel into parameter expression
        If oCell.Value = oParam.Name Then
            oParam.Expression = oCell.offset(0, 1).Value & oCell.offset(0, 2).Value
        End If
    Next oParam
Next oCell

' Close workbook
Call oWkbk.Close

Set oExcel = Nothing

' Update part/assembly
oDoc.Update
End Sub  

 

Message 7 of 11

Anonymous
Not applicable

 Kudos are much appreciated if the information I have shared is helpful to you and/or others.

 

 Did this resolve your issue? Please accept it "As a Solution" so others may benefit from it.

0 Likes
Message 8 of 11

Anonymous
Not applicable

Trevor,

I hope everything is well with out. I was able to modify the code you provided me to fit my need and it works. I also ended up writing a second version where the user will open an assembly, run the macro and then code would go through each part in assembly look into the excel match the parameter and so on. I tested the code surprisingly it works but I am not sure if efficient or structured right, I was hoping if you could take a look at it and see if your see problem with it or if you have suggestions on it. Thank you very much.

 

sincerely,

adam

Sub read_uparam_assy()
'*************************************browse for excel*******************************
    Dim Finfo As String
    Dim Title As String
    Dim FilterIndex As Long
    Dim file_selected As String
    Dim file_name As String
    ChDrive "C:\"
    ChDir "C:\"
    'set browser options
    Finfo = "Excel Files .xls,*.xls," & "Excel Files .xlsx,*.xlsx," & "Excel Files .xlsm,*.xlsm,"
    Title = "Select File"
    FilterIndex = 3
    file_selected = Application.GetOpenFilename(Finfo, FilterIndex, Title)
    'exit if user didn't select or cancel
    If file_selected = "False" Then
    Exit Sub
    Else
    file_name = file_selected
    End If
'**************************************excel****************************************
    'access excel file content
    Dim excelApp As Excel.Application
    'Try to connect to a running instance of Excel.
    On Error Resume Next
    Set excelApp = GetObject(, "Excel.Application")
    If Err Then
    Err.Clear
    'Couldn't connect so start Excel. It's started invisibly.
    Set excelApp = CreateObject("Excel.Application")
    If Err Then
    MsgBox "Cannot access excel."
    Exit Sub
    End If
    End If
    'You can make it visible if you want. This is especially
    excelApp.Visible = False
    'Open the spreadsheet.
    Dim wb As Workbook
    Set wb = excelApp.Workbooks.Open(file_name)
    If Err Then
    MsgBox "Unable to open the Excel document."
    'Exit Sub
    End If
    'Access a certain sheet.
    Dim ws As WorkSheet
    Set ws = wb.Sheets("output")
    If Err Then
    MsgBox "Unable to get the worksheet."
    'Exit Sub
    End If
    'Set range where parameter names reside in sheet
    'sParamRange = ws.Range("A1", ws.Range("A1").End(xlDown)).Rows.Count
    Dim sParamRange As String
    sParamRange = "A1:A4"
    Dim oCell As Range
    ' Loop through each parameter listed in sheet
For Each oCell In ws.Range(sParamRange)
'**************************************inventor****************************************
     'Get the active assembly document.
      Dim oAsmDoc As AssemblyDocument
      Set oAsmDoc = ThisApplication.ActiveDocument
     'Iterate through all of the documents refrenced by the assembly.
      Dim oDoc As Document
    For Each oDoc In oAsmDoc.AllReferencedDocuments
            'Check to see if this is a part.
            If oDoc.DocumentType = kPartDocumentObject Then
                Dim partDoc As PartDocument
                Set partDoc = oDoc
                Dim partDef As PartComponentDefinition
                Set partDef = partDoc.ComponentDefinition
             'define parameters
               Dim oUserParams As UserParameters
               Set oUserParams = partDef.Parameters.UserParameters
               Dim param As Parameter
            End If
        For Each param In oUserParams
          ' If names match, copy value and units from Excel into parameter expression
           If oCell.Value = param.Name Then
               param.Expression = oCell.Offset(0, 1).Value & oCell.Offset(0, 2).Value
           End If
        Next param
    Next oDoc
Next oCell
    wb.Close False
    wb.Close
    Set wb = Nothing
    Set ws = Nothing
    Set excelApp = Nothing
End Sub
Message 9 of 11

Anonymous
Not applicable

Adam,

 

Your code looks really good. I like how you implemented a check to see if there is already an instance of Excel running. There are only a couple of things I would do differently. One thing is to take all your declarations out of your nested For Each loop. The way you have it written, for every part in your assembly multiplied by the number of parameters you have in your Excel sheet, you will be declaring partDoc, partDef, oUserParams and params each time. For example, if you are checking for 10 parameters in 10 parts, you will be declaring each of these variables 100 times. These repetitive declarations are unnecessary and will slow your script down.

 

A less notable change would be to swap the oDoc and oCell For Each loops so that you're not checking to see if a referenced assembly is a part document over and over again.

 

And finally, I might add some update commands in there--one for each part and then a final update for the whole assembly. The Update2 call on the assembly will perform a global update on all referenced documents that need it, but depending on how your assembly is constrained, updating each part after modification may or may not be necessary to avoid sick constraints in the assembly. Adding an update to each part will slow down performance, so mess around with it and see if you need it or not.

 

This is how I would rewrite the code from line "For Each oCell" thru line "Next oCell". I hope this helps!

 

 

'Get the active assembly document.
Dim oAsmDoc As AssemblyDocument
Set oAsmDoc = ThisApplication.ActiveDocument

' Allocate space for variables
Dim oDoc As Document
Dim oPartDoc As PartDocument
Dim oPartDef As ComponentDefinition
Dim oUserParams As UserParameters
Dim param As Parameter
Dim oCell As Range

'Iterate through all of the documents refrenced by the assembly.
For Each oDoc In oAsmDoc.AllReferencedDocuments
    If TypeOf oDoc Is PartDocument Then
        Set oPartDef = oDoc.ComponentDefiniton
        Set oUserParams = oPartDef.UserParameters

        For Each oCell In ws.Range(sParamRange)
        
            For Each param In oUserParams
                ' If names match, copy value and units from Excel into parameter expression
                If oCell.Value = param.Name Then
                    param.Expression = oCell.offset(0, 1).Value & oCell.offset(0, 2).Value
                End If
            Next param
        Next oCell
        
        ' Update part document (this is optional and will slow down performance, but could
        ' prevent sick constraints in assembly once it updates. Update2(True) disregards
        ' errors
        Call oDoc.Update2(True)
    End If

Next oDoc

' Update assembly document, disregard errors
Call oAsmDoc.Update2(True)

 

Message 10 of 11

Anonymous
Not applicable

Trevor,

Thank you very much for your help. If you don't mind I would like to bother you for the last time, I have tried to figure it out but couldn't and I would appreciate it if you could help with this two question below when you get the chance:

        1. Instead of specifying "A1:A4" is there a line of code to do from A1:to last data?

        2. is it possible to include if parameter not found create them from the excel file or may be another version of macro to create the user parameter

            from the excel file?

 

Sincerely,

adam

0 Likes
Message 11 of 11

tonythm
Advocate
Advocate

Hello All,

 

Please help me about VBA excel.

I have the excel file parameter. I want write VBA code in excel file to output data to Inventor Parameter. Only working on Excel file that Inventor automation update.

I have attached example file.

 

Thank you.

0 Likes