changing SaveAs dialog leaves Name window blank

L

Larry

Jay Freedman recently pointed me to this code provided at the MVPs site
which opens the SaveAs dialog to the desired folder. However, it also
has the effect of leaving the Name window in the dialog blank instead of
putting the first several words of the document into the Name window by
default. If I remove the backslash following "tests", then "tests"
appears in the Name box. Is there any way I can modify this code as to
get its benefits while still keeping Word's default behavior of
displaying the first words of the document in the Name box?

With Dialogs(wdDialogFileSaveAs)
.Name = "C:\Documents\tests\"
.Show
End With

Thanks much,
Larry
 
J

Jezebel

Name:="C:\Documents\tests\" & left(ActiveDocument.Name, FirstFew)

where FirstFew is the number of characters you want. Windows allows up to
255, so you don't need to be stingy.
 
J

Jay Freedman

Hi, Jezebel,

Larry wants to emulate Word's default behavior -- showing the beginning of
the document's *content*, not the beginning of its name, but only if the
document hasn't already been saved. That makes the job a little more
complicated...

Sub foo()
Dim fn As String, rg As Range
With ActiveDocument
If (Dir(.Name) <> "") Or (.Words.Count = 1) Then
fn = .Name
Else
Set rg = .Words(1)
rg.End = .Words(min(9, .Words.Count - 1)).End
fn = Trim(rg.Text) & ".doc"
fn = Replace(fn, "\", "")
fn = Replace(fn, ":", "")
fn = Replace(fn, """", "")
fn = Replace(fn, vbCr, "")
fn = Replace(fn, vbTab, "")
End If
End With
With Dialogs(wdDialogFileSaveAs)
.Name = "C:\Documents\tests\" & fn
.Show
End With
End Sub

Private Function min(a As Long, b As Long)
min = -((a < b) * a + (a >= b) * b)
End Function

The If statement says that if the document has already been saved at least
once (so that the Dir function returns a non-empty string) or if the
document is blank (because the ever-present final paragraph mark counts as a
"word", you have to test for .Count = 1 instead of 0), then use the current
name. In the case of a blank unsaved file this will be like "Document1".

Otherwise (if the file is unsaved and not blank), the proposed filename will
be the first nine words of the document -- or all the words if there are
fewer than 9. The Replace functions strip out some characters that would be
illegal in a filename.

I'll leave the explanation of the min() function as an exercise for the
interested reader. :)
 
J

JGM

Hi Jay,

You bet I am an interested reader...
I have never seen an equation like the one you used in the min function:
min = -((a < b) * a + (a >= b) * b)

So, here is my "uneducated" guess (I have no training in programming or in
maths..., so bear with me!):
My premise is that
(a < b)
will return 0 if false or -1 if true.

So, if a = 9 (actually in your code it is always 9) and
b = 20 (the number of words in the document)
then
min = -((9 < 20) * 9 + (9 >= 20) * 20)
min = -((-1) * 9 + (0) * 20)
min = -((-9) + (0))
min = -(-9)
min = 9

or
if a = 9 and b = 5
min = -((9 < 5) * 9 + (9 >= 5) * 5)
min = -((0) * 9 + (-1) * 5)
min = -((0) + (-5))
min = -(-5)
min = 5

Is that it or am I just plain lucky so that it works, but not for the
reasons I state?

Finally,
fn = Replace(fn, "\", "")
fn = Replace(fn, ":", "")
fn = Replace(fn, """", "")
etc.
is necessary in this context,

But how do you include a Replace for a manual line break ("^l")
You cannot use
fn = Replace(fn, "^l", "")
or
fn = Replace(fn, VbLf, "")

So what is the magic trick?

Thanks!
 
J

Jay Freedman

Hi, Jean-Guy,

You win the prize! Yes, VBA uses the values 0 and -1 to represent the
Boolean values False and True. (The reason for the latter, I suspect, is
that -1 is represented in binary "twos complement" notation by 11111111,
which is equal to NOT 00000000.) Therefore you can multiply and add Boolean
expressions and integers in the same statement. This is really just showing
off, though. In the old days (maybe 10 years ago) such an expression was
much faster to calculate than If..Then statements, and that made a visible
difference in performance. Today it's much more important that the code
should be readable and understandable, so this code is preferable:

Private Function min(a As Long, b As Long) As Long
If a < b Then
min = a
Else
min = b
End If
End Function

The manual line break (^l in the Find dialog) is represented in VBA by the
named constant vbVerticalTab. (The ASCII value of the character and the
value of the constant are both 11.) So you could add the line

fn = Replace(fn, vbVerticalTab, "")
 
L

Larry

Jay, I believe the Replace statement does not exist in Word 97 VBA. Too
bad. Any other way to do this?

Larry
 
J

JGM

Hi Jay,

Actually I knew about the numerical value of Boolean results, but I did not
know that (a<b) inside an equation would act as a boolean expression....
that is what I meant by "uneducated" guess!

Thanks for the VbVerticalTab info. The idiots at Microsoft have it listed as
a constant in the Help (I had seen it previous to my earlier post) but they
say that it is no longer used in the Windows environment.... go figure!

Also, by doing some testing with that constant, I realize that Word counts
periods and commas as Words, so Larry might want to get rid of them in the
name string otherwise you might end up with something like:
"My document has exactly nine words in order..dot"
or
"My document has exactly nine words in order,.dot"
which looks funny!

Anyway,
Thanks for the info.
 
L

Larry

The problem is less commas and periods (since the number of words put in
the Name box doesn't need to be exact) than empty paragraph marks
preceding the beginning of the text. So in addition to getting Jay's
code working in Word 97, I'm also working on a way to start the choice
of the words at the first real text in the document, not at the
beginning of the document.

Larry
 
J

JGM

Hi Larry,

Try this function:
_______________________________________
Public Function ReplaceStr(ByVal str1 As String, ByVal repThis As String,
ByVal withThis As String) As String

Dim i As Long

While Left(str1, Len(repThis)) = repThis
str1 = withThis & Mid(str1, Len(repThis) + 1)
Wend

While InStr(2, str1, repThis) > 0
i = InStr(2, str1, repThis)
str1 = Left(str1, i - 1) & withThis & Mid(str1, i + Len(repThis))
Wend

ReplaceStr = str1

End Function
_______________________________________


I have used it in Excel 97 and it worked fine.

HTH
Cheers!
 
L

Larry

JGM,

If I'm supposed to use the macro Jay gave me, how do I change it to make
it work with this function? Or do I need a different macro to work with
this function?

Larry
 
L

Larry

Disregard the last message. I just had to change Replace in the macro
to ReplaceStr. It seems to work fine. Thanks very much!

Larry
 
L

Larry

However, I think I found a simpler way of accomplishing the same
thing--combining the two earlier macros that I had tried, in an If Then
structure. I use the first set of code for unsaved documents, and the
second for saved documents, while using ActiveDocument.Name to get the
document name in the Name window:


If ActiveDocument.Path = "" Then
' This older code only worked if the document was unsaved.
ChangeFileOpenDirectory ("C:\Documents\tests")
Application.Dialogs(wdDialogFileSaveAs).Show
' Display correct caption in case it had been previously changed
ActiveWindow.Caption = WordBasic.filenameinfo(ActiveDocument.Name, 4)
Else
With Dialogs(wdDialogFileSaveAs)
.Name = "C:\Documents\tests\" & ActiveDocument.Name
.Show
End With
' Display correct caption in case it had been previously changed
ActiveWindow.Caption = WordBasic.filenameinfo(ActiveDocument.Name, 4)

End If
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top