Save .idw files in .pdf and .dxf format based on drawing names and their paths listed in an Excel file.

Save .idw files in .pdf and .dxf format based on drawing names and their paths listed in an Excel file.

deak_peter
Contributor Contributor
1,481 Views
14 Replies
Message 1 of 15

Save .idw files in .pdf and .dxf format based on drawing names and their paths listed in an Excel file.

deak_peter
Contributor
Contributor

Hello everybody,

 

I would like your help with an excel file containing the exact names and paths of the drawings. What I would like to do is to open the specified drawings one by one from Inventor and save the drawings in pdf and dxf format to the location from where the excel file is opened.

Attached I attach the excel vba macro I have written so far and the image that excel will pull in and examine to see

where the drawings are located.

I would appreciate your help, this task takes a lot of time and effort in my work and I am trying to shorten the time invested.

 

Thank you and have a nice day everyone!

 

Code here:

' QuickSort function that arranges parts in alphabetical order
' Whether .IPT or .IAM file
Private Sub QuickSort(ByRef arr() As String, ByVal low As Long, ByVal high As Long)
    Dim pivot As Variant
    Dim i As Long, j As Long
    pivot = arr((low + high) \ 2)
    i = low
    j = high
    Do
        Do While arr(i) < pivot
            i = i + 1
        Loop
        Do While arr(j) > pivot
            j = j - 1
        Loop
        If i <= j Then
            Dim temp As String
            temp = arr(i)
            arr(i) = arr(j)
            arr(j) = temp
            i = i + 1
            j = j - 1
        End If
    Loop Until i > j
    If low < j Then QuickSort arr, low, j
    If i < high Then QuickSort arr, i, high
End Sub

Private Sub GetPartPaths(filePath As String)

    ' Create an array of access routes
    Dim pathArray() As String
    Dim fso As New FileSystemObject
    ReDim pathArray(0)
    Dim totalPaths As Integer

    If (fso.FileExists(filePath)) Then
        If (InStr(Join(pathArray), filePath) = 0) Then
            ReDim Preserve pathArray(UBound(pathArray) + 1)
            pathArray(UBound(pathArray)) = filePath
            totalPaths = totalPaths + 1
        End If
    Else
        'Case where the file cannot be found
    End If
End Sub

'Call the GetPartPaths function for each part
For Each oDoc In oApp.Documents
    If Right(oDoc.FullFileName, 4) = ".ipt" Or Right(oDoc.FullFileName, 4) = ".iam" Then
        If oDoc.FullFileName <> currentFile Then
            GetPartPaths (oDoc.FullFileName)
            iCounter = iCounter + 1
        End If
    End If
Next oDoc

'Routes stored in an array go back to the original code
For i = 0 To UBound(pathArray)
    'pathArray(i) contains the key of the sequence
Next i

Sub CountPart()
    Dim oApp As Application
    Dim oDoc As Document
    Dim iCounter As Integer
    Dim currentFile As String
    Dim xlApp As Excel.Application
    Dim xlWorkbook As Excel.Workbook
    Dim xlWorksheet As Excel.WorkSheet
    Dim lastRow As Long
    Dim pathArray() As String
    Dim fso As New FileSystemObject
    
    Dim oCompDef As Inventor.ComponentDefinition
    Set oCompDef = ThisApplication.ActiveDocument.ComponentDefinition

    
    iCounter = 0
    
    Set oApp = GetObject(, "Inventor.Application")
    currentFile = oApp.ActiveDocument.FullFileName
    ' Create an array to store the part names and paths
    Dim parts() As String
    ' Create an instance of Excel, add a workbook and a worksheet
    Set xlApp = New Excel.Application
    Set xlWorkbook = xlApp.Workbooks.Add
    Set xlWorksheet = xlWorkbook.Worksheets(1)
    xlWorksheet.Name = "Part List"
    ' Set the column headers
    xlWorksheet.Cells(1, 1).Value = "PartName"
    xlWorksheet.Cells(1, 2).Value = "PartPath"
    xlWorksheet.Cells(1, 3).Value = "Mass (Kg)"
    ' Iterate through the documents in the Inventor session
    
    For Each oDoc In oApp.Documents
        If Right(oDoc.FullFileName, 4) = ".ipt" Or Right(oDoc.FullFileName, 4) = ".iam" Then
            If oDoc.FullFileName <> currentFile Then
                ' Get the part name and path
                Dim partName As String
                Dim partPath As String
                partName = fso.GetFile(oDoc.FullFileName).Name
                partPath = fso.GetFile(oDoc.FullFileName).Path
                ' Append the data to the parts array
                On Error Resume Next
                ReDim Preserve parts(iCounter)
                parts(iCounter) = partName & ";" & partPath
                    If Err.Number <> 0 Then
                        ' Write the missing file name to a .txt file
                        Dim fs As Object
                        Set fs = CreateObject("Scripting.FileSystemObject")
                        Dim txtFile As Object
                        Set txtFile = fs.OpenTextFile("C:\Vault\Designs\missing_files.txt", 8, True)
                        txtFile.WriteLine (partName & ";" & partPath)
                        txtFile.Close
                        ' Reset the error handling
                On Error GoTo 0
                    Else
                iCounter = iCounter + 1
            End If
        End If
    End If
    Next oDoc
    
    ' Sort the parts array in ascending alphabetical order
    If iCounter = 0 Then
        MsgBox "There are no .ipt and .iam files in the Inventor session.", vbOKOnly, "IPT and IAM File Count"
        Exit Sub
    End If
    QuickSort parts, 0, UBound(parts)
    
    ' Prompt the user to select the location to save the data, create variable to represent the Inventor.FileDialog
    Dim saveDlg As Inventor.FileDialog
    'this method sets the value of that variable you just created, without using 'Set' keyword
    Call ThisApplication.CreateFileDialog(saveDlg)
    saveDlg.DialogTitle = "Select the location to save the data"
    saveDlg.Filter = "Excel Files (*.xlsx)|*.xlsx|All files (*.*)|*.*"
    saveDlg.FilterIndex = 1
    saveDlg.CancelError = True
    On Error Resume Next 'pause normal error handling
    Call saveDlg.ShowSave 'this is a Sub, so no 'Return' value
    If Err <> 0 Then Exit Sub 'if Error when showing dialog, then exit Sub
    If saveDlg.fileName = "" Then Exit Sub 'if nothing selected, exit Sub
    ' Create the text file and write the sorted parts to it
        For i = 0 To UBound(parts)
            Dim partData() As String
            partData = Split(parts(i), ";")
            xlWorksheet.Cells(lastRow, 1).Value = partData(0)
            xlWorksheet.Cells(lastRow, 2).Value = partData(1)
            lastRow = lastRow + 1
        Next i
        
    ' Save the workbook and close Excel
    xlWorkbook.SaveAs saveDlg.fileName, FileFormat:=xlOpenXMLWorkbook
    
    'Close the original Excel document
    xlWorkbook.Close
    xlApp.Quit
    
    MsgBox "There are " & iCounter & " .ipt and .iam files in the Inventor session." & vbCrLf & "Data has been saved to: " & saveDlg.fileName, vbOKOnly, "IPT and IAM File Count"

End Sub

Sub OpenIDW_v1()
    Dim xlApp As Excel.Application
    Dim xlBook As Excel.Workbook
    Dim xlSheet As Excel.WorkSheet
    Dim idwFile As String
    Dim pdfComplete As Boolean
    Dim dxfComplete As Boolean
    
    ' Prompt user to select Excel file
    Set xlApp = CreateObject("Excel.Application")
    xlApp.DisplayAlerts = False
    Dim xlFilename As Variant
    xlFilename = xlApp.GetOpenFilename("Excel Files (*.xls*), *.xls*", , "Select Excel File to Open")
    If xlFilename = False Then Exit Sub
    
    ' Open Excel file and select worksheet
    Set xlBook = xlApp.Workbooks.Open(xlFilename)
    Set xlSheet = xlBook.Worksheets(1)
    
    ' Get number of file paths in column B
    Dim lastRow As Long
    lastRow = xlSheet.Cells(xlSheet.Rows.Count, 2).End(xlUp).Row
    
    ' Loop through rows in Excel worksheet
    For i = 1 To lastRow
        ' Get IDW file path from Excel cell
        idwFile = xlSheet.Cells(i, 2).Value
        
        ' Open IDW file in Autodesk Inventor
        Call ThisApplication.Documents.Open(idwFile)
        
        ' Prompt user to confirm PDF and DXF backup is complete
        
        Dim filePath As String
        Dim fileName As String
        Dim fileNameWithPath As String
        
        filePath = ThisDoc.Path
        fileName = ThisDoc.fileName(False) 'without extension
        fileNameWithPath = filePath & "\" & fileName
        
        ThisDoc.Document.SaveAs fileNameWithPath & ".dxf", True
        ThisDoc.Document.SaveAs fileNameWithPath & ".pdf", True
    
        pdfComplete = MsgBox("Is the PDF backup complete?", vbYesNo) = vbYes
        dxfComplete = MsgBox("Is the DXF backup complete?", vbYesNo) = vbYes
        
        ' Close IDW file if PDF and DXF backup is complete
        If pdfComplete And dxfComplete Then
            Call ThisApplication.ActiveDocument.Close(True)
        End If
    Next i
    
    ' Close Excel file
    xlBook.Close SaveChanges:=False
    xlApp.Quit
    
    Set xlSheet = Nothing
    Set xlBook = Nothing
    Set xlApp = Nothing
End Sub

 

I would like to receive your comments and advice on how to improve it in code!

0 Likes
Accepted solutions (2)
1,482 Views
14 Replies
Replies (14)
Message 2 of 15

A.Acheson
Mentor
Mentor

Hi @deak_peter 

  • I havent had a chance to test this but I see two lines of code that are ilogic and not VBA. ThisDoc needs to be changed to the active document or document object referenced earlier. 
ThisDoc.Document.SaveAs fileNameWithPath & ".dxf", True
        ThisDoc.Document.SaveAs fileNameWithPath & ".pdf", True
    

 

Can you post the error messages your seeing and where the errors are located? 

 

  • I see also code with no start Sub line and end sub. I would suggest to pick one sub routine and get it to work before integrating another. 
'Call the GetPartPaths function for each part
For Each oDoc In oApp.Documents
    If Right(oDoc.FullFileName, 4) = ".ipt" Or Right(oDoc.FullFileName, 4) = ".iam" Then
        If oDoc.FullFileName <> currentFile Then
            GetPartPaths (oDoc.FullFileName)
            iCounter = iCounter + 1
        End If
    End If
Next oDoc

'Routes stored in an array go back to the original code
For i = 0 To UBound(pathArray)
    'pathArray(i) contains the key of the sequence
Next i
  • Excel application object is referenced twice in seperate sub routines instead of having an object past through as an argument. 

Those are just a few quick items I noticed so if you want to start with the start sub routine and trouble shoot that please post it up and hopefully someone can review.

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 3 of 15

deak_peter
Contributor
Contributor

hello @A.Acheson,

 

Thanks the answer. I attach the excel codes and the autodesk codes in a .txt file.

 

I hope everything will be all right.

 

 

0 Likes
Message 4 of 15

A.Acheson
Mentor
Mentor

Hi @deak_peter 

I see you have attached VBA codes for both excel and inventor. You can drive the process from either one so I would choose  one and stick with it. The main thing is to reference the dll your using so you can access the objects. I personally would choose inventor because this is where I would be working most of the time and would like the nacro button in the ribbon. What is your preference? 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 5 of 15

deak_peter
Contributor
Contributor

Hello @A.Acheson 

 

Hello,

The parts list is received in excel and that's why I thought of having 2 platforms, so that the workflows are not separated. I personally would try Inventor, however unfortunately I could not embed the excel codes in Inventor. If I could possibly ask for your help with this as well as saving the .idw files then I would appreciate it.

 

0 Likes
Message 6 of 15

A.Acheson
Mentor
Mentor

Ok I would suggest start with the inventor code so and just get that to function correctly. Have you tested this? The excel  functions might be missing correct objects referencing and may need to be changed to work from within inventor.

 

Unfortuantley I won't have a lot of time to do any testing for you but if you can post up any error messages when you get a chance then hopefully I or another VBA user can walk you through what's wrong.  

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 7 of 15

deak_peter
Contributor
Contributor

hello @A.Acheson,

 

My original plan was to process what we get as an excel file there and then do the last step only in Inventor. All steps work, only the pdf/dxf save I can't decode based on my excel list.

I need a program that looks for the path in column B in an excel spreadsheet, opens it in inventor, automatically starts the pd/dxf save and then exits and goes to the next row in column B.

The rest is all functional and in use, if you have anything to improve (lighter code, more options to process,...etc) I'd be happy to.
Thanks for your help.

Peter

0 Likes
Message 8 of 15

A.Acheson
Mentor
Mentor

Hi @deak_peter 

Here is the helpfile for creating a PDF from a drawing file. If you go one step back you will find the dxf translator also.

Can you attach the code your using to launch inventor from excel? Is this where your having the trouble?

This post here has the sub routine to achieve this. 

Sub OpenInventorDocumentFromExcel()
Dim strFile As String
strFile = "Fill In Full Filename of the document"

Dim InvApp As Inventor.Application

'If you like to create a new inventor instance
Set InvApp = CreateObject("Inventor.Application")

'if you like to use an open instance of inventor

'Set inventorApp = GetObject(, "Inventor.Application")
InvApp.Visible = True
Call InvApp.Documents.Open(strFile, False)

End Sub
If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 9 of 15

deak_peter
Contributor
Contributor

Hello @A.Acheson 

 

Here is my code to open inventor drawing file from excel and try to save pdf and dxf.

Sub OpenIDW_v1()
    Dim xlApp As Excel.Application
    Dim xlBook As Excel.Workbook
    Dim xlSheet As Excel.WorkSheet
    Dim idwFile As String
    Dim pdfComplete As Boolean
    Dim dxfComplete As Boolean
    
    ' Prompt user to select Excel file
    Set xlApp = CreateObject("Excel.Application")
    xlApp.DisplayAlerts = False
    Dim xlFilename As Variant
    xlFilename = xlApp.GetOpenFilename("Excel Files (*.xls*), *.xls*", , "Select Excel File to Open")
    If xlFilename = False Then Exit Sub
    
    ' Open Excel file and select worksheet
    Set xlBook = xlApp.Workbooks.Open(xlFilename)
    Set xlSheet = xlBook.Worksheets(1)
    
    ' Get number of file paths in column B
    Dim lastRow As Long
    lastRow = xlSheet.Cells(xlSheet.Rows.Count, 2).End(xlUp).Row
    
    ' Loop through rows in Excel worksheet
    For i = 1 To lastRow
        ' Get IDW file path from Excel cell
        idwFile = xlSheet.Cells(i, 2).Value
        
        ' Open IDW file in Autodesk Inventor
        Call ThisApplication.Documents.Open(idwFile)
        
        ' Prompt user to confirm PDF and DXF backup is complete
        
        Dim filePath As String
        Dim fileName As String
        Dim fileNameWithPath As String
        
        filePath = ThisDoc.Path
        fileName = ThisDoc.fileName(False) 'without extension
        fileNameWithPath = filePath & "\" & fileName
        
        ThisDoc.Document.SaveAs fileNameWithPath & ".dxf", True 'Just try my problem solution but i cant
        ThisDoc.Document.SaveAs fileNameWithPath & ".pdf", True 'Just try my problem solution but i cant
    
        pdfComplete = MsgBox("Is the PDF backup complete?", vbYesNo) = vbYes
        dxfComplete = MsgBox("Is the DXF backup complete?", vbYesNo) = vbYes
        
        ' Close IDW file if PDF and DXF backup is complete
        If pdfComplete And dxfComplete Then
            Call ThisApplication.ActiveDocument.Close(True)
        End If
    Next i
    
    ' Close Excel file
    xlBook.Close SaveChanges:=False
    xlApp.Quit
    
    Set xlSheet = Nothing
    Set xlBook = Nothing
    Set xlApp = Nothing
End Sub

 

This code is in my Autodesk Inventor VBA editor.

0 Likes
Message 10 of 15

A.Acheson
Mentor
Mentor
Accepted solution

Hi @deak_peter 

I see some issues here

  1. Your using ilogic only functions to get this document. This won't work in VBA.

 

ThisDoc.Document

This should be declared earlier when you open the drawing file.

Dim oDrawDoc As DrawingDocument
Set oDrawDoc = ThisApplication.Documents.Open(idwFile,True)

 

  • Your using the saveas method to convert drawing to pdf. I would suggest use the translator as the quality will be better than just saving and you have more control over the options. 

The below code assumes your running this in inventor VBA. You will need to supply a filename = "c:\temp\test.pdf".

The code is not tested!

 

Sub OpenIDW_v1()
    Dim xlApp As Excel.Application
    Dim xlBook As Excel.Workbook
    Dim xlSheet As Excel.WorkSheet
    Dim idwFile As String
    Dim pdfComplete As Boolean
    Dim dxfComplete As Boolean
    
    ' Prompt user to select Excel file
    Set xlApp = CreateObject("Excel.Application")
    xlApp.DisplayAlerts = False
    Dim xlFilename As Variant
    xlFilename = xlApp.GetOpenFilename("Excel Files (*.xls*), *.xls*", , "Select Excel File to Open")
    If xlFilename = False Then Exit Sub
    
    ' Open Excel file and select worksheet
    Set xlBook = xlApp.Workbooks.Open(xlFilename)
    Set xlSheet = xlBook.Worksheets(1)
    
    ' Get number of file paths in column B
    Dim lastRow As Long
    lastRow = xlSheet.Cells(xlSheet.Rows.Count, 2).End(xlUp).Row
    
    ' Loop through rows in Excel worksheet
    For i = 1 To lastRow
        ' Get IDW file path from Excel cell
        idwFile = xlSheet.Cells(i, 2).Value
        
        ' Open IDW file in Autodesk Inventor
        Dim oDrawDoc As DrawingDocument
        Set oDrawDoc = ThisApplication.Documents.Open(idwFile,True)
        
        ' Prompt user to confirm PDF and DXF backup is complete      
        pdfComplete = MsgBox("Is the PDF backup complete?", vbYesNo) = vbYes
        dxfComplete = MsgBox("Is the DXF backup complete?", vbYesNo) = vbYes

         Call PublishPDF(oDrawDoc)
        
        ' Close IDW file if PDF and DXF backup is complete
        If pdfComplete And dxfComplete Then
            oDrawDoc.Close(True)
        End If
    Next i
    
    ' Close Excel file
    xlBook.Close SaveChanges:=False
    xlApp.Quit
    
    Set xlSheet = Nothing
    Set xlBook = Nothing
    Set xlApp = Nothing
End Sub

Public Sub PublishPDF(oDocument As DrawingDocument)
    ' Get the PDF translator Add-In.
    Dim PDFAddIn As TranslatorAddIn
    Set PDFAddIn = ThisApplication.ApplicationAddIns.ItemById("{0AC6FD96-2F4D-42CE-8BE0-8AEA580399E4}")

    Dim oContext As TranslationContext
    Set oContext = ThisApplication.TransientObjects.CreateTranslationContext
    oContext.Type = kFileBrowseIOMechanism

    ' Create a NameValueMap object
    Dim oOptions As NameValueMap
    Set oOptions = ThisApplication.TransientObjects.CreateNameValueMap

    ' Create a DataMedium object
    Dim oDataMedium As DataMedium
    Set oDataMedium = ThisApplication.TransientObjects.CreateDataMedium

    ' Check whether the translator has 'SaveCopyAs' options
    If PDFAddIn.HasSaveCopyAsOptions(oDocument, oContext, oOptions) Then

        ' Options for drawings...

        oOptions.Value("All_Color_AS_Black") = 0

        'oOptions.Value("Remove_Line_Weights") = 0
        'oOptions.Value("Vector_Resolution") = 400
        'oOptions.Value("Sheet_Range") = kPrintAllSheets
        'oOptions.Value("Custom_Begin_Sheet") = 2
        'oOptions.Value("Custom_End_Sheet") = 4

    End If

    'Set the destination file name
    oDataMedium.FileName = "c:\temp\test.pdf"

    'Publish document.
    Call PDFAddIn.SaveCopyAs(oDocument, oContext, oOptions, oDataMedium)
End Sub

 

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 11 of 15

deak_peter
Contributor
Contributor

Hello @A.Acheson,

 

The code works perfectly. I have so many questions, what method or code do you recommend to save all documents with their own name to the same folder where I retrieved the excel file from in the beginning.

 

Peter

0 Likes
Message 12 of 15

deak_peter
Contributor
Contributor

Hello @A.Acheson 

 

Also, I forgot to ask, what is the way to save the dxf? Can PublishPDF be copied to dxf format?

 

Péter

0 Likes
Message 13 of 15

A.Acheson
Mentor
Mentor
Accepted solution

Hi @deak_peter 

You can use file system object to retrieve filepath and filename. You actually used it in your original code.

Here is the helpfile for fso

 

    

                Dim fso As New FileSystemObject

                ' Get the part name and path
                Dim partName As String
                Dim partPath As String
                partName = fso.GetFile(oDoc.FullFileName).Name
                partPath = fso.GetFile(oDoc.FullFileName).Path
                ' Append

 And from the API help here is the link to DXF translator.

Screenshot_20230601_224449_Chrome.jpg

 

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 14 of 15

deak_peter
Contributor
Contributor

Thank you a lots of help.

0 Likes
Message 15 of 15

deak_peter
Contributor
Contributor

Hello @A.Acheson,

 

Based on the code you see above, is there a way to save the mass of each part collected when Countpart runs?

0 Likes