Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations JAE on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

SW Custom Property Linking in Excel's VB 11

Status
Not open for further replies.

puds

Mechanical
Joined
Jun 25, 2007
Messages
40
Location
CA
I am not a programmer at all, however I have managed to create myself and my company a quick and easy way of tracking our drawings. I simply created a spreadsheet in Excel that automatically updates on open & lists all files in our drawing vault folder by their filename and adds a hyperlink to each of these files. I now want to add the corresponding description, customer name & project # from the custom properties of each of the solidworks files so that they will display in the spreadsheet also, therefore giving us a means of finding our documents without knowing the exact part number. Right now, I have the spreadsheet working so that column A lists the files and hyperlinks them, column B lists the Last Modified Date & column C shows the file path. Column D heading shows Description, Column E heading shows Customer & Column F shows Project, just like they should. However I do not understand how I can retrieve the custom property values and have them added into my spreadsheet. If anybody could help, that would be awesome. Here is my code so far:

Private Sub WORKBOOK_OPEN()
' Searches the selected folders and sub folders for files with the specified
'extension. .xls, .doc, .ppt, etc.
'A new worksheet is produced called "File Search Results". You can click on the link and go directly
'to the file you need.
Dim i As Long, z As Long, Rw As Long
Dim ws As Worksheet
Dim y As Variant
Dim fLdr As String, Fil As String, FPath As String

y = "*.*"
If y = False And Not TypeName(y) = "STRING" Then Exit Sub
Application.ScreenUpdating = False

'**********************************************************************
'fLdr = BrowseForFolderShell
fLdr = "P:\DRAWING_VAULT"

'**********************************************************************
With Application.FileSearch
.NewSearch
.LookIn = fLdr
.SearchSubFolders = False
.Filename = y
Set ws = ThisWorkbook.Worksheets.Add(Sheets(1))
On Error GoTo 1
2: ws.Name = "TMC_DRAWING_LIST"
On Error GoTo 0
If .Execute() > 0 Then
For i = 1 To .FoundFiles.Count
Fil = .FoundFiles(i)
'Get file path from file name
FPath = Left(Fil, Len(Fil) - Len(Split(Fil, "\")(UBound(Split(Fil, "\")))) - 1)
If Left$(Fil, 1) = Left$(fLdr, 1) Then
If CBool(Len(Dir(Fil))) Then
z = z + 1
ws.Cells(z + 1, 1).Resize(, 6) = _
Array(Dir(Fil), _
FileDateTime(Fil), _
FPath, _
'***this is where I would assume I need to add the callouts for description, customer & project**
)



ws.Hyperlinks.Add Anchor:=Cells(z + 1, 1), _
Address:=.FoundFiles(i)
End If
End If
Next i
End If
End With

ActiveWindow.DisplayHeadings = False

With ws
Rw = .Cells.Rows.Count
With .[A1:F1]
.Value = [{"FILE NAME (CLICK TO OPEN)","LAST MODIFIED", "PATH"," FILE DESCRIPTION","CUSTOMER","PROJECT/WORKORDER NO."}]
.Font.ColorIndex = vbBlack
.Font.Bold = True
.Font.Size = 11
.Cells.Interior.Color = vbGreen
.EntireColumn.AutoFit
.HorizontalAlignment = xlCenter
End With
.[G1:IV1 ].EntireColumn.Hidden = True
On Error Resume Next
Range(Cells(Rw, "A").End(3)(2), Cells(Rw, "A")).EntireRow.Hidden = True
Range(.[A2 ], Cells(Rw, "C")).Sort [A2 ], xlAscending, Header:=xlNo
End With

Application.ScreenUpdating = True
Exit Sub
1: Application.DisplayAlerts = False
Worksheets("TMC_DRAWING_LIST").Delete
Application.DisplayAlerts = True
GoTo 2
End Sub












 
Whoops, sorry, I misread my object browser. It's just

DSO.Open SFileName:=fil, ReadOnly:=True, Options:=dsoOptionOpenReadOnlyIfNoWriteAccess
 
perfect....works like a charm. Thank you so much....AGAIN! This little spreadsheet is saving us so much time, it's great. The only thing I am thinking about doing differently is having it so you open the spreadsheet and it shows the sheet that was last saved. Then you can hit a button if you want it to update. That way it will save sometime when opening. Is this a simple change?
 
well i just moved the code from workbook to a new module and added the macro toolbar to excel. Now I can just save the spreadsheet when it closes and next time I open it, it will be how it was at its last save. I can hit the run macro button to update it now. Does this seem okay to you or is there a better way of doing it? I would like to have an "UPDATE DRAWING LIST" button appear when the spreadsheet opens that will run the macro when it is clicked. Is there a way to do this?
 
actually forget about my last post - someone here thought it would be a good idea to automatically run the macro and save the spreadsheet when you close the workbook. That way when you open it again, it will be updated (unless someone else added files between the last close and the opening). Anyways, I think this may be a good way to do it. Any ideas?
 
Well the autosave on close is a good idea, however it causes a slight problem if someone else has the spreadsheet open at the same time. If I have the file open and then another user open it and closes it while I have the write version open, his will crash with an error because it doesnt have write access to update and then save the file since I have it open. Anybody have any better suggestions on doing this? The only reason I didn't leave the update on open is because with more files being created everyday, it takes longer and longer to open the spreadsheet and update. Is there anyway to make it realtime updateable?
 
Why not update it every night with a scheduled task or script? You could use VBScript to un-read-onlify the file, open it, run the update, save, close, and re-read-onlify it again. Then, just have some computer run that task at midnight or something.
 
Is there a way to have each of the users only be able to open a read only copy of the file and have the writeable copy on a timed interval to update and then save itself again? If so, is there also a way so that the read only copies will refresh everytime the writeable version updates, even if the user currently has the read only copy open for viewing?

I guess what I would really like to happen is to have the file as a viewing file only with the ability to update at timed intervals by a writeable version running in the background or something along those lines. Any ideas?
 
I would probably make the original file to be read-only. Then, you can add the following block of code at the beginning of the WORKBOOK_OPEN() sub:

Code:
If ActiveWorkbook.ReadOnly Then
    MsgBox "Sheet last updated " & ActiveWorkbook.BuiltinDocumentProperties("Last Save Time")
    Exit Sub
End If

This will stop the main update code from running if the file was opened read-only. Having the file open read-only will keep the original file available for periodic updating (more on that later). If you want to give users the option of getting the latest data without waiting for the periodic update (or changing the read only status of the master file!), you can use the following block instead. It will ask the user upon opening the document whether or not they want to go retrieve the latest data:

Code:
    If ActiveWorkbook.ReadOnly Then
        Dim sMsg As String
        sMsg = "Sheet last updated " & ActiveWorkbook.BuiltinDocumentProperties("Last Save Time")
        sMsg = sMsg & vbCrLf & vbCrLf & "File is currently open as read-only."
        sMsg = sMsg & vbCrLf & "Accept the currently saved values?" & vbCrLf
        sMsg = sMsg & "Choosing ""No"" will increase time required to open."
        If MsgBox(sMsg, vbYesNo) = vbYes Then
            Exit Sub
        End If
    End If

Now, take the following block of code and paste it into a new text file in Notepad and save it as a ".vbs" (for VBScript) file.

Code:
const WBPATH = "ENTER THE PATH TO YOUR EXCEL FILE HERE"

dim xlApp		'Excel Application Object
dim xlWorkbook	'Excel Workbook object
dim sWkBkPath	'String
dim fso		'File System Object
dim wbFile		'File object

set fso = createobject("Scripting.FileSystemObject")
set wbFile = fso.getfile(WBPATH)

if wbfile.attributes AND 1  then
	wbfile.attributes = wbfile.attributes - 1
end if


set xlApp = CreateObject("Excel.Application")

set xlWorkbook = xlApp.Workbooks.Open(WBPATH)

xlApp.Visible = FALSE  'Make true if you want to see the workbook

xlWorkbook.Save

xlWorkbook.Close
xlApp.Quit

set wbFile = fso.getfile(WBPATH)

if not (wbfile.attributes AND 1) then
	wbfile.attributes = wbfile.attributes + 1
end if

set xlWorkbook = Nothing
set xlApp = Nothing
set wbFile = Nothing
set fso = Nothing

This little script will set the master file to be non-read-only, open the file (which runs the update macro), save the file, close the file, and set it back to read only. Of course, you'll have to put the path to your Excel file in that WBPATH constant at the very top.

Once you've done that, you can use Windows Task Scheduler to run the script on whatever schedule you want. Just go to Control Panel, choose Scheduled Tasks, and use the "Add Scheduled Task" icon to schedule it. Note that the wizard that starts automatically is really pretty limited. However, if you check the box for "Open Advanced Properties" on the last page of the wizard you can set up whatever kind of schedule you want. Once a day, twice a day, once an hour, every minute, whatever you like.

Hope this helps!
 
Handleman I have to say that this is super sweet. My only slight problem now is that if I select "no" when I open the spreadsheet and update it, when I go to close it, excel gives me a pop-up window asking if I would like to save my changes. If I select no, it closes and everything is fine. If I select yes, it opens the save as window since the copy I have open is read only. Is there any way to force excel to not ask if I would like to save the sheet if I update the read only version? I have it set to update automatically through your script every 10 minutes, so I don't need to worry about saving the read only updated sheet. I really see this as my last obstacle for this thing. Thank you so much for all of your help. There is definitely no way I would have been able to do this without you and the other on this forum. Once I have it done, I am thinking about zipping it all up and posting it here.
 
You can suppress that dialog by adding the subroutine:

Code:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ActiveWorkbook.Saved = True
End Sub

You're basically lying to Excel, telling it that you've not really made any changes since the last save. You can tell Excel this "ActiveWorkbook.Saved = True" lie anywhere in code you want. Excel will believe you until you make another change to the workbook.
 
Handleman, I have a new problem! We recently got a external drive system that we have added to our network as a shared drive. I moved all of our drawing files to this drive, including the folder containing all of this excel workbook. Now when I try to run the program, I get the following error:

run-time error - 2147287039 (80030001)
Method 'open' of object '_oledocumentproperties' failed

I am thinking that some kinda of reference is missing suddenly, or something strange. Let me know if you have any ideas. Thanks.
 
A lot can change in six months... could you post a current copy of your code, and specify which line is causing the error? If you wish, you could just upload a copy of the spreadsheet via the new file attachment capability.
 
Sub workbook_open()

If ActiveWorkbook.ReadOnly Then
Dim sMsg As String
sMsg = "*********************************"
sMsg = sMsg & vbCrLf & "TMC DRAWING DATABASE NOTIFICATION" & vbCrLf
sMsg = sMsg & vbCrLf & "*********************************" & vbCrLf
sMsg = sMsg & vbCrLf & "THIS SHEET WAS LAST UPDATED: " & ActiveWorkbook.BuiltinDocumentProperties("Last Save Time") & vbCrLf
sMsg = sMsg & vbCrLf & vbCrLf & "Select ""YES"" to continue with current data"
sMsg = sMsg & vbCrLf & "Select ""NO"" to update the data" & vbCrLf
sMsg = sMsg & vbCrLf & "***************************************************************" & vbCrLf
sMsg = sMsg & "HINT: CHOOSING ""No"" WILL INCREASE THE TIME TO OPEN THIS SHEET"
If MsgBox(sMsg, vbYesNo) = vbYes Then
Exit Sub
End If
End If
Dim i As Long, z As Long, Rw As Long
Dim ws As Worksheet
Dim y As Variant
Dim fLdr As String
Dim fil As String
Dim DSO As DSOFile.OleDocumentProperties
Dim FPath As String

Dim Object As String
Set OBJFILE = CreateObject("DSOFile.OleDocumentProperties")
y = "*.*"
If y = False And Not TypeName(y) = "STRING" Then Exit Sub
Application.ScreenUpdating = False

'**********************************************************************
'fLdr = BrowseForFolderShell
fLdr = "x:\"

'**********************************************************************

With Application.FileSearch
.NewSearch
.LookIn = fLdr
.SearchSubFolders = False
.Filename = y


Set ws = ThisWorkbook.Worksheets.Add(Sheets(1))
On Error GoTo 1
2: ws.Name = "TMC DRAWING LIST"
On Error GoTo 0
If .Execute() > 0 Then
For i = 1 To .FoundFiles.Count
fil = .FoundFiles(i)
Set DSO = New DSOFile.OleDocumentProperties
crashes here----> DSO.Open SFileName:=fil, ReadOnly:=True, Options:=dsoOptionOpenReadOnlyIfNoWriteAccess


'Get file path from file name




FPath = Left(fil, Len(fil) - Len(Split(fil, "\")(UBound(Split(fil, "\")))) - 1)
If Left$(fil, 1) = Left$(fLdr, 1) Then
If CBool(Len(Dir(fil))) Then
z = z + 1
ws.Cells(z + 1, 1).Resize(, 8) = _
Array(Dir(fil), _
DSO.SummaryProperties.DateLastSaved, _
IsProp(DSO.CustomProperties, "Description"), _
IsProp(DSO.CustomProperties, "material"), _
IsProp(DSO.CustomProperties, "Customer"), _
IsProp(DSO.CustomProperties, "Project"), _
IsProp(DSO.CustomProperties, "UserDefined1"), _
IsProp(DSO.CustomProperties, "UserDefined2"), _
IsProp(DSO.CustomProperties, "LINE_NO"), _
IsProp(DSO.CustomProperties, "LINE_DESC"), _
IsProp(DSO.CustomProperties, "PRODUCT_DESC"), _
IsProp(DSO.CustomProperties, "PRODUCT_CONF"))




ws.Hyperlinks.Add Anchor:=Cells(z + 1, 1), _
Address:=.FoundFiles(i)
End If
End If
Next i
End If
End With

ActiveWindow.DisplayHeadings = False

With ws
Rw = .Cells.Rows.Count
With .[a1:L1]
.Value = [{"FILE NAME (CLICK TO OPEN)","LAST MODIFIED"," FILE DESCRIPTION","MATERIAL","CUSTOMER","WORKORDER NO.","COMPUTER ID NO.","CUSTOMER DWG NO.","LINE NO.","LINE DESCRIPTION","PRODUCT DESCRIPTION","PRODUCT CONFIGURATION"}]
.Font.ColorIndex = vbBlack
.Font.Bold = True
.Font.Size = 11
.Cells.Interior.Color = vbGreen
Range("A1").AutoFilter field:=1, Criteria1:="*", VisibleDropDown:=True
.EntireColumn.AutoFit
.HorizontalAlignment = xlLeft



End With
.[M1:IV1 ].EntireColumn.Hidden = True

On Error Resume Next
Range(Cells(Rw, "A").End(3)(2), Cells(Rw, "A")).EntireRow.Hidden = True
Range(.[A2 ], Cells(Rw, "C")).Sort [A2 ], xlAscending, Header:=xlNo

End With

Application.ScreenUpdating = True
Exit Sub
1: Application.DisplayAlerts = False
Worksheets("TMC DRAWING LIST").Delete
Application.DisplayAlerts = True
GoTo 2


End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ActiveWorkbook.Saved = True
End Sub




Function IsProp(myCProps As Object, myMemName As String) As String
Dim testProp As Object
On Error Resume Next
Set testProp = myCProps(myMemName)
If testProp Is Nothing Then
IsProp = "N/A"
Else
IsProp = testProp.Value
End If
On Error GoTo 0
End Function





 
The program crashes on DSO.Open SFileName:=fil, ReadOnly:=True, Options:=dsoOptionOpenReadOnlyIfNoWriteAccess

I thought it may be a missing reference, but its not as far as I know. The strange thing is that it can make it through Solidworks files in the that folder no problem, its other files such as step files or autocad files that it chokes on. Maybe I missing a reference for those? I don't see why it would change though. Oh and just so you know, all that I have done is moved the folder which contained this spreadsheet as well as all of the drawings to a new shared drive on an external hard drive. I am wondering if it is possible if that new drive isn't allowing this function or something along those lines?? My error is;

Run-time error -2147287039 (800300001)
Method 'Open' of object '_OleDocumentProperties' failed
 
This is pretty strange. I'm not able to reproduce the error on my end. You say that SolidWorks files work fine. Just for fun, can you try changing the line:

y = "*.*"

to

y = "*.sld*"

and see if the program will run all the way through for you? If so, and if you only want to list SW files, then I guess you're set. Otherwise, we'll have to dig a bit more.

Do you have any details about your "external drive system"? Encryption? Compression? Firewall?
 
haha, this is strange. I changed to y = "*.sldprt" and the program ran through without an error, however it didn't actually list and of the solidworks files in the spreadsheet. It just created the spreadsheet with all of the headings but nothing listed beneath. I am starting to think more and more that this is a external drive problem. I will try some things on the drive and repost in a while. By the way, I still want to be able to list all file types in that folder, or atleast all solidworks files (.sldprt,.sldasm,.slddrw), all autocad formats (.dxf,.dwg) and PDF files if possible. Is it likely that a firewall or security setting on the new drive may be the problem?
 
That's why I suggested changing to

y = "*.sld*"

instead of

y = "*.sldprt"

*.sld* should get you all SolidWorks files, and should also help if you're somehow getting into DOS style 8.2 file naming issues.
 
Tried it, still didn't work. Changed the security settings on the NAS to allow everyone full control and it didn't help. I am confused.....I read before it is working fine on your end?
 
Yes, working fine. I have no problems at all on my end. What were the results with y = "*.sld*"? Same as "*.sldprt" (program runs, but no files found)?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top