Ilogic Search through all subfolders of a directory

Ilogic Search through all subfolders of a directory

MKE_Howard
Collaborator Collaborator
1,711 Views
7 Replies
Message 1 of 8

Ilogic Search through all subfolders of a directory

MKE_Howard
Collaborator
Collaborator

Hi, I'm no expert in ilogic code but I need help. I'm looking through a lot of posts but I can't find a way so if someone have an idea, please help. 

 

My goal : Have an Ilogic code that look through all the parts in an assembly, then check if they have a drawings created.

If the part have a drawing : Run an external rule

If the part doesn't have a drawing : tells me which one (I dont care how I didn't figure out yet)

 

So I "stole😂" a code from a post. Everything works but the problem is my drawings are in a different folder. Im trying to make it search through all subfolder from a defined path. Here is the code :

Imports System.IO
Dim oAss As AssemblyDocument = ThisApplication.ActiveDocument
Dim oRefDoc As Document
Dim ofilepath As String = "D:\ThisIsThePathIWant"
Dim oArray As New ArrayList

For Each oRefDoc In oAss.AllReferencedDocuments
	Dim ofilename As String
	ofilename = Left(oRefDoc.DisplayName, oRefDoc.DisplayName.Length - 4) & ".idw"
	If System.IO.File.Exists(ofilepath & ofilename) = False
		oArray.Add(oRefDoc.DisplayName)
	End If
Next

Do
odrawing = InputListBox("Prompt", oArray)
If odrawing = "" Then Return
For Each oRefDoc In oAss.AllReferencedDocuments
	If oRefDoc.DisplayName = odrawing
		ThisApplication.Documents.Open(oRefDoc.FullDocumentName)
	End If
Next
oArray.Remove(odrawing)
Loop

 I don't need help for the external rule thing I will find a way by my own but I really need help for the looking through every folder. Thanks a lot

Accepted solutions (1)
1,712 Views
7 Replies
Replies (7)
Message 2 of 8

WCrihfield
Mentor
Mentor

Hi @MKE_Howard.  This seems like an odd request, and I am not sure we have enough information to create a usable example for you, but here is a similar functioning rule to your request.  It specifies a base folder where all drawings are expected to be stored directly within.  It uses a 'List(Of String) collection type variable to keep track of the models that no drawing file was found for.  It then iterates through all the active document's referenced documents, getting its file name (without path or file extension), then combines that with the path where the drawings are supposed to be, and the file extension of a drawing.  Then tries to find that drawing file.  If not found, the FullDocumentName of that model is added to the list, and if it is found, it can run an external rule, but I left that line commented out, because we do not know that name of that external rule, or what document that external rule is supposed to be focused on when it runs.  If you plan on that rule focusing on that referenced document, then you may need to activate the referenced document first, to make it visible, otherwise your external rule may not be acting upon the correct document when it runs.  Then at the end, if anything was added to the list, it will show that information in a List, and log the entries to the iLogic Log window.

Dim oDoc As Document = ThisDoc.Document
Dim sDrawingsFolder As String = "C:\Temp\MyDrawings"
Dim oModelsWithoutDrawing As New List(Of String) 'to hold FullDocumentName of models needing drawings
Dim oRefDocs As DocumentsEnumerator = oDoc.AllReferencedDocuments
If oRefDocs.Count = 0 Then Return
For Each oRefDoc As Document In oRefDocs
	'get file name of oRefDoc, without path or file extension
	Dim sFileName As String = System.IO.Path.GetFileNameWithoutExtension(oRefDoc.FullFileName)
	'put drawing folder, file name, and drawing file extension together to get full file name of drawing file
	Dim sDrawingFile As String = sDrawingsFolder & "\" & sFileName & ".idw"
	'check if that file exists
	If System.IO.File.Exists(sDrawingFile) = False Then
		'if the file was not found, add this referenced document object to the 'List' of documents needing a drawing
		oModelsWithoutDrawing.Add(oRefDoc.FullDocumentName)
	Else 'the drawing file was found
		'iLogicVb.Automation.RunExternalRule(oDocumentForTheRuleToTarget, "External Rule Name")
	End If
Next
If oModelsWithoutDrawing.Count > 0 Then
	'show the user a list of FullDocumentNames of the models needing drawings
	a = InputListBox("", oModelsWithoutDrawing, "", "Models Needing Drawings")
	Logger.Info("List Of Models Needing Drawings:" & vbCrLf)
	For Each sFDN In oModelsWithoutDrawing
		Logger.Info(sFDN)
	Next
End If

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 8

J-Camper
Advisor
Advisor

@MKE_Howard,

 

This should look at the directory set by "oFilepath", from your posted code, and all sub directories within it and create a list of file paths for all .idw files:

Dim fNamesList As List(Of String) = System.IO.Directory.EnumerateFiles(ofilepath, "*.idw", System.IO.SearchOption.AllDirectories).ToList()

 

 

0 Likes
Message 4 of 8

MKE_Howard
Collaborator
Collaborator
I got this code but I have an error or the Line 10 (Value of type 'System.Collections.Generic.List(Of String)' cannot be converted to string):

Dim oAss As AssemblyDocument = ThisApplication.ActiveDocument
Dim oRefDoc As Document
Dim ofilepath As String = "MyPath"
Dim fNamesList As List(Of String) = System.IO.Directory.EnumerateFiles(ofilepath, "*.idw", System.IO.SearchOption.AllDirectories).ToList()
Dim oArray As New ArrayList

For Each oRefDoc In oAss.AllReferencedDocuments
Dim ofilename As String
ofilename = Left(oRefDoc.DisplayName, oRefDoc.DisplayName.Length - 4) & ".idw"
If System.IO.File.Exists(fNamesList) = False
oArray.Add(oRefDoc.DisplayName)
End If
Next

Do
odrawing = InputListBox("Prompt", oArray)
If odrawing = "" Then Return
For Each oRefDoc In oAss.AllReferencedDocuments
If oRefDoc.DisplayName = odrawing
ThisApplication.Documents.Open(oRefDoc.FullDocumentName)
End If
Next
oArray.Remove(odrawing)
Loop
0 Likes
Message 5 of 8

WCrihfield
Mentor
Mentor

Hi @MKE_Howard.  There still seems to be multiple things wrong with the code you just posted, but I can explain the error you mentioned encountering.  That line of code:

If System.IO.File.Exists(fNamesList) = False

...is specifying the entire list of files as the input, when it is just looking for a single full file name.  And it can not convert that List(Of String) object (that is what fNamesList represents) into just a simple String.  If you want to supply one of the drawing files from the list as input there, then you must specify just one of the entries within the list, instead of the whole list...like fNamesList.Item(0), where Item zero would be the first entry in the list, if it contains any entries.  That list will contain the full file name of every file with the ".idw" file extension that was found in the directory specified by 'ofilepath', and any files like that within any of its sub directories.  If there were no files like that found in that directory, then the list will still be empty.  Also, just so you know, the Document.DisplayName property is Read/Write, and sometimes it contains the file name with file extension, but other times it just contains file name, without extension.  Therefore it is not a super stable file specification to use.  It would be more stable to get the file name, without extension, of the existing referenced document using something like the following line of code:

For Each oRefDoc In oAss.AllReferencedDocuments
Dim ofilename As String
'gets file name, without path or file extension
ofilename = System.IO.Path.GetFileNameWithoutExtension(oRefDoc.FullFileName) & ".idw"

...but just the file name, with no path, can not be used to check if a file exists.  When using the System.IO.File.Exists() method, you must specify a full file name, which includes the full path, file name, and extension.  Will the drawing have the same file name as the model file, just a different path?  If so, then you may need to find the drawing file in the list that has the same file name as the referenced document first, then if that can be found in the list, you know you have a drawing for it.  The files in the list will already exist, because those files were already found, so no need to check if the files in the list exist.  You would only need to check if a file exists if you are 'guessing' at the drawing's path, then combining that with the model file name to see if that file exists.  If doing it that way, then the initial list that was gathered from the other directory will likely not be useful for much.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 6 of 8

MKE_Howard
Collaborator
Collaborator
First thanks for answering and explaining everything. To answer your question, yes the drawings will have the same name as the 3d model. If I understood correctly, the function System.IO.File.Exists() need 1 path but the fNameList is a list of multiple path. Is this would be a good idea if I create a loop that look through every path then if something is found with the same name, to return that information in a variable and then use my System.IO.File.Exists()?
0 Likes
Message 7 of 8

JelteDeJong
Mentor
Mentor
Accepted solution

Have a look at this rule. It starts by opening the log so it can give information like the files that are not found. Then it will find all drawing files (and notify you if it finds files with the same name). Last it will open the files that you are looking for.

Dim pathToSearch = "D:\forum\"

Dim loggerWindow = ThisApplication.UserInterfaceManager.DockableWindows.Cast(Of DockableWindow).
        Where(Function(d) d.InternalName.Equals("ilogic.logwindow")).First()
loggerWindow.Visible = True

Dim doc As AssemblyDocument = ThisDoc.Document
Dim modelFileNames = doc.AllReferencedDocuments.Cast(Of Document).Select(Function(d) d.FullFileName)

Dim expectedDrawingNames As New List(Of String)
For Each modelFile As String In modelFileNames
    expectedDrawingNames.Add(System.IO.Path.GetFileNameWithoutExtension(modelFile))
Next

Dim foundDrawingFiles = System.IO.Directory.EnumerateFiles(pathToSearch, "*.idw", System.IO.SearchOption.AllDirectories).ToList()
Dim foundDrawingFileDictonary As New Dictionary(Of String, String)()

For Each foundDrawingFileFull As String In foundDrawingFiles
    Dim drawingName = System.IO.Path.GetFileNameWithoutExtension(foundDrawingFileFull)
    If (foundDrawingFileDictonary.ContainsKey(drawingName)) Then
        Logger.Info("Found 2 files with the same name. Will only show results for first item.")
        Logger.Info(" - " & foundDrawingFileDictonary(drawingName))
        Logger.Info(" - " & foundDrawingFileFull)
    Else
        foundDrawingFileDictonary.Add(drawingName, foundDrawingFileFull)
    End If
Next

For Each expectedFile As String In expectedDrawingNames
    If (foundDrawingFileDictonary.ContainsKey(expectedFile)) Then
        Logger.Info("Opening file: " & foundDrawingFileDictonary(expectedFile))
        ThisApplication.Documents.Open(foundDrawingFileDictonary(expectedFile))
    Else
        Logger.Info("Could not find file: " & expectedFile)
    End If
Next

 

Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Blog: hjalte.nl - github.com

Message 8 of 8

MKE_Howard
Collaborator
Collaborator
Hi, I feel bad because you did the whole code but thanks a lot. It works and this is what I wanted. I will change some of it to complete everything for my project. Thanks again!
0 Likes