VBA File Dialog .FileName removing .1 from end of file name - vba

I am using visual basic to write a Macro for Autodesk Inventor. I created a macro that calls a file dialog, see code below. Everything works fine except when a user puts a file name in with a period and a number greater than zero following it.
For example, if a user puts testfile.test in the box and hits ok. When I ask for what they put in there using .FileName, I get "testfile.test". Just like I should.
However, if the user puts testfile.1 or testfile.10 or testfile.1mdksj or anything as long as a number greater than zero directly follows the period I get back "testfile". For some reason, everything after the period and the period gets removed.
What is the reason for this? Is this a bug in visual basic or am I doing something wrong?
'Set up the file dialog
Dim oFileDlg As FileDialog
' Create a new FileDialog object.
Call ThisApplication.CreateFileDialog(oFileDlg)
'Define the filter to select part and assembly files or any file.
oFileDlg.Filter = "All Files (*.*)|*.*"
'Define the part and assembly files filter to be the default filter.
oFileDlg.FilterIndex = 1
'Set the title for the dialog.
oFileDlg.DialogTitle = "Save File As"
'Tell the dialog box to throw up and error when cancel is hit by user
oFileDlg.CancelError = True
'Show the file dialog
On Error Resume Next
oFileDlg.ShowSave
'save the user specified file
Dim newFileName As String
newFileName = oFileDlg.FileName
UPDATE:
I ended up doing the following "hack" to make things still work while dealing with a period:
oFileDlg.fileName = sFname & "."
oFileDlg.ShowSave
fullName = Left$(oFileDlg.fileName, Len(oFileDlg.fileName) - 1)
That worked fine for quite a while on Windows 7 and then Windows 10. Unfortunately, the Windows 10 Creative update seems to have changed how the file dialog works. With the above code, fullName would come back blank if there were no periods in the name and would truncate everything from the FIRST period from the left if there was a period in the name.
I'm not really sure what changed in Windows 10, but it pretty much destroyed my hack. Windows 7 still works fine and Windows 10 before the creative update works. I ended up doing the following to make everything work again in the version of Windows I mentioned above.
oFileDlg.fileName = sFname & ".00"
oFileDlg.ShowSave
fullName = Left$(oFileDlg.fileName, Len(oFileDlg.fileName) - 3)

This is a VB property, but it may extend to VBA as well. Have you tried setting the save settings to support multidotted extensions? Try something like this:
SupportMultiDottedExtensions = True
This setting is intended permit the use dotted extensions - meaning the use of periods in the file name. See this MSDN reference for documentation and information: http://msdn.microsoft.com/en-us/library/system.windows.forms.filedialog.supportmultidottedextensions.aspx#Y129
This SO article may also shed further light: SaveAs Dialog with a period in the filename does not return extension
EDIT
After checking the autodesk documentation - a difficult and unpleasant task, in my opinion - there does indeed appear to be no support for MultidottedExtensions. I did, however, find a function on VBAExpress that I have very closely adapted. The function can be used to filter strings with contain unacceptable characters. Jimmy Pena's blog has an excellent function for just such a purpose: http://www.jpsoftwaretech.com/excel-vba/validate-filenames/. I have only substantively added a period and a replace to the code:
'A function for filtering strings, with a focus on filenames.
Function FilterFileNameString(stringToScrub As String) As String
'Filters a filename string - or any string for that matter.
Dim FilteredString As String
'A highly nested replace function.
FilteredString = Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(stringToScrub, ".","|", ""), ">", ""), "<", ""), Chr(34), ""), "?", ""), "*", ""), ":", ""), "/", ""), "\", "")
'Returns filtered string.
FilterFileNameString = FilteredString
End Function
Jimmy Pena's blog also contains a recursive version as well, although he does not recommend it.
You can filter any strings to be used as filenames with another character - a space in this case. You could use an underscore, however, or any other character you deemed pleasant.
In general, if you are trying to use periods for versioning or a similar purpose, and inventor will not let you, I would strongly advise going to another character or set of characters that can provide such an indication, such an underscore "_", a numbering system, "001", "002", a lettering system, "AAA", "AAB", or whatever makes sense for your focus.
If you are just making the application user-friendly, I would suggest filtering the strings entered before saving them in the desired filetype, and separate the filtering of the strings from the save dialog if the period filtering gives you grief. It may add an extra step, but it may be the best and easiest way to filter out pesky invalid characters without creating unnecessary extra hassles for your users.
~JOL

Related

Word automation failing on server, but dev station works great

I am automating a oft-used paper form by querying the user on a web page, then modifying a base Word document and feeding that modified doc file to the user's browser for hand-off to Word.
The code is Visual Basic, and I am using the Microsoft.Office.Interop module to manipulate the document by manipulating Word. Works fine on the development system (Visual Studio 2015) but not on the production server (IIS 8.5).
Both the Documents.Open() call and the doc.SaveAs() call fail with Message="Command failed" Source="Microsoft Word" HResult=0x800A1066
Things I've tried:
Added debugging out the whazoo: Single-stepping is not an option on the production machine, so I pinpointed the problem lines with debug output.
Googled and found that this problem has been reported as early as 2007, but no viable solutions were reported.
A couple sites mentioned timing issues, so I added several pauses and retries -- none helped.
Some mentioned privileging, so I tried changing file permissions & application pool users -- neither helped.
Enhanced my exception handling reports to show more details and include all inner exceptions. That yielded the magic number 800A1066 which led to many more google hits, but no answers.
Added fall-back code: if you can't open the main document, create a simple one. That's when I found the SaveAs() call also failing.
Dropped back to the development system several times to confirm that yes, the code does still work properly in the right environment.
Greatly condensed sample code does not include fallback logic. My Word document has a number of fields whose names match the XML tokens passed as parameters into this function. saveFields() is an array of those names.
Dim oWord As Word.Application
Dim oDoc As Word.Document
oWord = CreateObject("Word.Application")
oWord.Visible = True
oDoc = oWord.Documents.Open(docName)
Dim ev As String
For i = 0 To saveFields.Length - 1
Try
ev = dataXD.Elements(saveFields(i))(0).Value
Catch
ev = Nothing
End Try
If ev IsNot Nothing Then
Try
Dim field = oDoc.FormFields(saveFields(i))
If field IsNot Nothing Then
If field.Type = Word.WdFieldType.wdFieldFormTextInput Then
field.Result = ev
End If
End If
Catch e As Exception
ErrorOut("Caught exception! " & e.Message)
End Try
End If
Next
...
oDoc.SaveAs2(localDir & filename)
oDoc.Close()
oWord.Quit(0, 0, 0)
The code should generate a modified form (fields filled in with data from the parameters); instead it fails to open, and the fallback code fails to save the new document.
On my dev system the document gets modified as it should, and if I break at the right place and change the right variable, the fallback code runs and generates the alternate document successfully -- but on the production server both paths fail with the same error.
Barring any better answers here, my next steps are to examine and use OpenXML and/or DocX, but making a few changes to the existing code is far preferable to picking a new tool and starting over from scratch.
Unfortunately, Lex Li was absolutely correct, and of course, the link to the reason why is posted on a site my company considers off limits, thus never showed up in my google searches prior to coding this out.
None of the tools I tried were able to handle the form I was trying to automate either -- I needed to fill in named fields and check/uncheck checkboxes, abilities which seemed beyond (or terribly convoluted in) the tools I evaluated ...
Eventually I dug into the document.xml format myself; I developed a function to modify the XML to check a named checkbox, and manipulated the raw document.xml to replace text fields with *-delimited token names. This reduced all of the necessary changes to simple string manipulation -- the rest was trivial.
The tool is 100% home-grown, not dependent upon any non-System libraries and works 100% for this particular form. It is not a generic solution by any stretch, and I suspect the document.xml file will need manual changes if and when the document is ever revised.
But for this particular problem -- it is a solution.
This was the closest I got to a complicated part. This function will check (but not uncheck) a named checkbox from a document.xml if the given condition is true.
Private Shared Function markCheckbox(xmlString As String, cbName As String, checkValue As Boolean) As String
markCheckbox = xmlString
If checkValue Then ' Checkbox needs to be checked, proceed
Dim pos As Integer = markCheckbox.IndexOf("<w:ffData><w:name w:val=""" & cbName & """/>")
If pos > -1 Then ' We have a checkbox
Dim endPos As Integer = markCheckbox.IndexOf("</w:ffData>", pos+1)
Dim cbEnd As Integer = markCheckbox.IndexOf("</w:checkBox>", pos+1)
If endPos > cbEnd AndAlso cbEnd > -1 Then ' Have found the appropriate w:ffData element (pos -> endPos) and the included insert point (cbEnd)
markCheckbox = markCheckbox.Substring(0, cbEnd) & "<w:checked/>" & markCheckbox.Substring(cbEnd)
End If
' Any other logic conditions, return the original XML string unmangled.
End If
End If
End Function

Visio: DOS Sharing violation (Error 1532)

So I'm really confused right now. Out of the blue my code gets me the error "DOS Sharing violation".
It's weird because, it says that is trying to save my document, but I just want to open it.
This is my Code:
Public Sub ReadActivity()
Dim vsoDocument As Visio.Document
Dim vsoPage As Visio.Page
Set vsoDocument = Documents.Open("C:\Users\Philip\Dropbox\Test\Aktivität0.vsdx")
Set vsoPage = vsoDocument.Pages(1)
SvgExport (ActiveDocument.path & "\files_and_images\" & Left(ActiveDocument.name, (InStrRev(ActiveDocument.name, ".", -1, vbTextCompare) - 1)) & ".svg")
CreateCodeActivity
vsoDocument.Close
End Sub
So as you might see the code is simple nothing special is going on.
Before calling the method I'm using this for encoding my textfile: VBA : save a file with UTF-8 without BOM
And two things are very weird. First of all, I used this method two days in a row for coding the method "CreateCodeActivity" and I didn't have any problems. And second, if I call the method let's say three times, on the third time everything works perfectly...
Where might be the problem?
Thank you #Shmukko for the tip, it is really the windows defender that gives me the error.
For Windows 10 the solution is: Go to Settings and select Update & security -> Windows Defender. Select Exclude a file extension and enter the file type for Visio.
That's it.

Why has my VB.net program decided to be case fussy?

I have a small VB.net program that opens some text files, 2 Excel files, a PDF file & creates a new Word document, or opens it if it already exists. Nothing clever, no databases & it works just fine.
I have just bought a Lima device (https://meetlima.com) and have moved my data & program onto the HD attached to it. This is showing on my PC as the "L" drive and everything seems to work EXCEPT the program has now decided to be fussy about the case of the data names !!!
For instance, this code worked just fine before I moved it from my "D" drive to "L" when trying to use the file Tes1 when the value of myLeftCB is TES
myRARfile = myFolder + myLeftCB + mySession + ".zip"
Now I have had to edit the code to this
myRARfile = myFolder + StrConv(myLeftCB, VbStrConv.ProperCase) + mySession + ".zip"
The trouble is, there are a number of similar checks & I don't really want to change all of them, if possible I'd just like to know why something has changed, and where, so I can hopefully change it back !!!
Because Lima is a separate device acting as a file system it's almost certain to be running some form of *nix and that means a case sensitive file system. In order to map case insensitive Windows filenames onto case-sensitive storage they must be doing some magic, leading to your unexpected results.
I agree with #Steve that you're going to have to seek answers from the vendor documentation for this one. In particular, examine the technical documentation to see if there are settings that control how case sensitivity is managed.
If you've got a number of places where this code is duplicated then I'd say that you've already got a weak point in your code. I suggest replacing all of those lines with call to a function that returns the filename. That's a pain to do but it replaces the code duplication so if you have to change the code in future you're only changing it in one place. Your code is easier to maintain and when the Lima vendors change their API in two months you'll only have to change the code in one place to fix it.

Run .exe from VB.NET fails on some systems?

I'm trying to run an .exe from my VB.NET application. On my system, everything works fine (Win7) but when i sent it to my friend for him to try (Win8), all it does is to open the .exe folder location in explorer.
Here's the code im using to run it:
Public fsxPath As String = My.Computer.Registry.GetValue(
"HKEY_CURRENT_USER\Software\Microsoft\Microsoft Games\Flight Simulator\10.0", "AppPath", Nothing)
Function startFsx()
' Do some things...
Process.Start(fsxPath & "fsx.exe")
Form1.ListView1.Items.Add("Work: START FSX.exe successfull")
Return True
End Function
Anyone know why it doesn't work for my friend?
Edit:
Okey so i tried everything i can think of now... On my PC the fsxPath when i show it in an Msgbox as follows:
Msgbox("Path:" & fsxPath & "fsx.exe")
For me, it returns "C:\FSX\fsx.exe
For my friend however it just returns "G:\Flight Simulator X\", the fsx.exe part is missing...
I don't know why it cuts the search path, however my solution was to assign the value to a text label and then assign the fsxExePath with the value of the label as follows:
' Hack to get fsxExePath...
Label1.Text = fsxPath
Label1.Text = Label1.Text & "fsx.exe"
fsxExePath = Label1.Text
Label1.Text = ""
Oh! 7 years later. Hope this would help someone :
The string you get from the registry will likely retain a null terminator at the end of the string to mark the end of that string. That's because the registry API is an old code, reminiscent of C/C++, and that null char terminator (&h00) is still there, you won't just see it via MsgBox/MessageBox because it was not meant to be meaningful visually anyway.
The first thing you do when you get a string from the registry is to make sure you have no null terminator anywhere :
Process.Start(fsxPath.Replace(vbNullChar, "") & "fsx.exe")
If you let the null terminator there, it appears dot Net handling of string value on his system will just discard whatever char/string you have after that null terminator. Appending "fsx.exe" after the string from the registry won't give you a valid executable to launch, only FSX directory, why it is opened in the explorer.
As to why it worked on your system despite being an older version (Win7 agains Win8) is for Microsoft to answer. Maybe Win8 is smelly, or the dotNet version on his computer is a version that overlooked that null terminator from registry retrieved string.
It works in the label, probably because the label Text property itself handles the existence of a null terminated string.
Anyway, I explained the likely cause. If I'm wrong, you get the point : maybe there is a line break, or one of the non printable char.. Just validate the string from the registry before using it.

FORMTEXT Appearing in Word File Name Generated from Protected Form-Field Value and BookMark for VB Script

I am using the following VB Script in a Word 2010 Doc saved as a Microsoft Word Macro-Enabled Template that is protected for form fields:
Sub SaveWithBkMarkedText()
'This code saves the Word file using the bookmark value for Maintenance Memo.
'The file is also saved to a folder in KnowHow for files related to this template.
Dim FileName As String
FileName = ActiveDocument.Bookmarks("mmn").Range.Text
'Use the C:\ code when saving the file locally
ActiveDocument.SaveAs "C:\Download\TemplatesFolders\" & FileName & ".doc"
MsgBox "Your Draft has been saved to KnowHow's Release Documentation site." & _
&vbCrLf & "The file name uses the MM that you included earlier: " & FileName, _
vbInformation + vbOKOnly, "Draft Saved to Minerva"
End Sub
The value entered into the Form Field for a FORMTEXT legacy-form object uses the Bookmark as the file name. Example, if the user enters 12345 as the value, the file is saved using this value as the filename: 12345.doc. This worked fine until a week ago when the filename is now being Prefixed with FORMTEXT 12345.doc. I have tried using this same VB script in older versions of Word on a different machine, and created from a NEW Template with the script added in from scratch, and the same issue is appearing on that machine as well. Prior to this, I was able to update my template with NO problem, but now I can't update this one FORMTEXT field without it affecting the whole file. I can update any other FORMTEXT in the template that does not use the Bookmark value as the file name, and it works. Also, I have tried changing the Bookmark Reference to another FORMTEXT object, as well as saving the file as a .DOCX and the same problem occurs regardless. What is causing the FORMTEXT to appear in the filename?
You have to un-protect the document (template) and then make the VBA programming. Once it is done, then you can protect it again (for filling forms) and you will not see the "FORMTEXT" in the filename when you run the macro.
Hope it helps.
To the OP, did you resolve this issue? I'm now having the same problem, I'm using form field text with bookmarks and using VB.net to get the bookmark.text which is now prefixed with FORMTEXT, just using a bookmark on it own and its OK, no prefix. I'm going to try and remove the first 9 characters from the result using code, a workaround, yes but it might work.
Know this is an old thread but ran into same issue. As a workaround...
Replace FORMTEXT with null "". In OP circumstance:
Dim FileName As String
FileName = ActiveDocument.Bookmarks("mmn").Range.Text
FileName = Replace(FileName, "FORMTEXT ", "")
Not a "fix" for the issue or elegant but it works.
Had the same issue. Simply delete current bookmark and add a new one. If that does not work than instead of using the following:
FileName = ActiveDocument.Bookmarks("mmn").Range.Text
try using:
Selection.GoTo What:=wdGoToBookmark, Name:="mmn"
Filename = Selection.Text