Declare Sub Sleep Lib "kernel32.dll" ( ByVal dwMilliseconds As Lon

J

Jeff

Greetings,
I Have a few questions, and am quite stumped
1. In Word is there an alternitive to the API call to pause the applications
progress?
2. Does the Sleep Procedure halt the OS or just the application?
3. My over all problem is I am moving a file from one folder to the another.
The trouble is at runtime I get a "Permission denied" error, If I place a
Break Point on the sub procedure to move the file or step through it it
works fine this problem only occurs @ runtime. See Code below

Sub MovePrintedFile(ByVal sFileName As String)
Dim oFSO As Object
Dim sDestinationFolder As String

On Error GoTo MovePrintedFile_Error

sDestinationFolder = "\\NetworkShare\ShareA\SomePath\"
Set oFSO = CreateObject("Scripting.FileSystemObject")

If Not oFSO.FolderExists(sDestinationFolder) Then
oFSO.CreateFolder (sDestinationFolder)
End If

'throws error here @ runtime
' No error if Breakpoint placed here or stepped through
Call oFSO.MoveFile(sFileName, sDestinationFolder)

MovePrintedFile_Exit:
Set oFSO = Nothing
Exit Sub

MovePrintedFile_Error:
Debug.Print sFileName & vbCr & Err.Description
Stop
Resume MovePrintedFile_Exit
End Sub
 
J

Jonathan West

Jeff said:
Greetings,
I Have a few questions, and am quite stumped
1. In Word is there an alternitive to the API call to pause the
applications
progress?

Depends on what you are trying to achieve.
2. Does the Sleep Procedure halt the OS or just the application?

It halts the current thread. Since all VBA runs in a single thread, it halts
the execution of the macro.
3. My over all problem is I am moving a file from one folder to the
another.
The trouble is at runtime I get a "Permission denied" error, If I place a
Break Point on the sub procedure to move the file or step through it it
works fine this problem only occurs @ runtime. See Code below

Sub MovePrintedFile(ByVal sFileName As String)
Dim oFSO As Object
Dim sDestinationFolder As String

On Error GoTo MovePrintedFile_Error

sDestinationFolder = "\\NetworkShare\ShareA\SomePath\"
Set oFSO = CreateObject("Scripting.FileSystemObject")

If Not oFSO.FolderExists(sDestinationFolder) Then
oFSO.CreateFolder (sDestinationFolder)
End If

'throws error here @ runtime
' No error if Breakpoint placed here or stepped through
Call oFSO.MoveFile(sFileName, sDestinationFolder)

MovePrintedFile_Exit:
Set oFSO = Nothing
Exit Sub

MovePrintedFile_Error:
Debug.Print sFileName & vbCr & Err.Description
Stop
Resume MovePrintedFile_Exit
End Sub

I would avoid using FSO for the purpose, because of precisely these issues
over timing.

Instead, you can use Windows API commands to create the folder.

Randy Birch has code for creating nested folders here
http://vbnet.mvps.org/code/file/nested.htm

Unfortunately Randy's code samples aren't quite drop-in-and-go, so you need
to proceed as follows

1. Create a new module.
2. Copy all the "Form code" from that page into the new module.
3. Delete the whole of the following routines (not needed): Command1_Click,
Command2_Click, CreateNestedFoldersByArray
4. In the function CreateNestedFoldersByPath, delete all lines of code that
make any reference to Label1, List1 or List2.
5. Change the declaration of CreateNestedFoldersByPath from Private to
Public.

You now have a function CreateNestedFoldersByPath which you can call from
elsewhere in your program. Pass to it the full pathname of the folder you
want to create. It will create as many folders as are needed in order to
ensure that the specified path exists.


For moving a file, if your source and destination folders are on the same
drive, then you can use the Name command to move a file. (Renaming a file,
including it's full pathname, has the effect of "moving" it). If you can't
guarantee that that source and destination are on the same drive, then it is
better to use a Windows API command, specifically SHFileOperation.

Randy Birch also has sample code here
http://vbnet.mvps.org/code/shell/shfileopadv.htm for this, but it isn't so
easy to strip it down to a simple drop-in working routine. I strongly
recommend you experiment with his full code sample, but for your immeduate
purposes, take the following and paste it into a new module

Option Explicit

Private Type SHFILEOPSTRUCT
hWnd As Long
wFunc As Long
pFrom As String
pTo As String
fFlags As Integer
fAborted As Boolean
hNameMaps As Long
sProgress As String
End Type

Private Const FOF_SILENT As Long = &H4
Private Const FOF_NOCONFIRMATION As Long = &H10

Private Declare Function SHFileOperation Lib "shell32" _
Alias "SHFileOperationA" _
(lpFileOp As SHFILEOPSTRUCT) As Long


Const FileMove As Integer = 1

Public Function ShellMove(ByVal sSource As String, _
sDestination As String) As Long

Dim FOF_FLAGS As Long
Dim SHFileOp As SHFILEOPSTRUCT

'terminate the folder string with a pair of nulls
sSource = sSource & Chr$(0) & Chr$(0)


'set up the options
With SHFileOp
.wFunc = FileMove
.pFrom = sSource
.pTo = sDestination
.fFlags = FOF_SILENT Or FOF_NOCONFIRMATION
End With

'and perform the move operation
ShellMove = SHFileOperation(SHFileOp)

End Function



When you call the ShellMove function, pass to it the full pathname of the
file to be moved, and the destination path. The destination can either be a
folder - in which case the filname is not changed, or it can be a full
pathname including filename, in which case the file is both moved and
renamed in a single process.
 
K

Karl E. Peterson

After serious thinking Jonathan West wrote :
I would avoid using FSO for the purpose,
^^^
You seem to have misspelled "any" - HTH! ;-)
Instead, you can use Windows API commands to create the folder.

Randy Birch has code for creating nested folders here
http://vbnet.mvps.org/code/file/nested.htm

Unfortunately Randy's code samples aren't quite drop-in-and-go,

Yeah, kinda ugly, when PureVB works pretty well. Here's one I tossed
together a few weeks ago, in answer to a similar query:

Public Function MkDirs(ByVal Folder As String) As Boolean
Dim f() As String
Dim attr As Long
Dim first As Long
Dim i As Long

' Split incoming folder into subfolders.
f = Split(Folder, "\")
For i = 1 To UBound(f)
f(i) = f(i - 1) & "\" & f(i)
Next i

' If the input path is UNC, the first element
' will be empty and the second "\", so we need
' to adjust where we start creating folders.
If f(0) = "" And UBound(f) > 0 Then
If f(1) = "\" Then
first = 4 'fourth element is first path.
End If
End If

' Use errors to signal need to take action.
On Error Resume Next
For i = first To UBound(f)
' Check if this level already exists.
attr = GetAttr(f(i))
If Err.Number Then
' Folder likely doesn't exist,
' clear error and create.
Err.Clear
MkDir f(i)
If Err.Number Then Exit For
End If
Next i

' Return success?
MkDirs = CBool(GetAttr(Folder) And vbDirectory)
End Function

There's also a very simple API approach you can take, if you are able
to restrict yourself to Windows ME/2000 and beyond:

Private Declare Function SHCreateDirectoryExW Lib "shell32" (ByVal
hWnd As Long, ByVal lpszPath As Long, ByVal lpSA As Long) As Long

Public Function PathMakeDirs(ByVal Path As String) As Boolean
Dim nRet As Long
' Potential error codes.
Const ERROR_SUCCESS As Long = 0&
Const ERROR_FILENAME_EXCED_RANGE As Long = 206&
Const ERROR_BAD_PATHNAME As Long = 161&
Const ERROR_PATH_NOT_FOUND As Long = 3&
Const ERROR_FILE_EXISTS As Long = 80&
Const ERROR_ALREADY_EXISTS As Long = 183&
Const ERROR_CANCELLED As Long = 1223&
' Requires v5.0 of Shell32.dll...
nRet = SHCreateDirectoryExW(0&, StrPtr(Path), 0&)
' Treat "already exists" as success...
PathMakeDirs = _
(nRet = ERROR_SUCCESS) Or _
(nRet = ERROR_FILE_EXISTS) Or _
(nRet = ERROR_ALREADY_EXISTS)
End Function

The thread:

http://groups.google.com/group/micr...read/thread/fc22d2eb5bec18e7/dc8ca8616a596287
 
J

Jeff

Thanks For the help guys. The FSO created the folder correctly my trouble
lied in the MoveFile method. The code was trying to move the file while still
printing.
Which brings me to another question aside from setting the Background
parameter to True in th Application.PrintOut method is there a way to
suppress the Printing Dialog box?
 
D

Doug Robbins - Word MVP

ActiveDocument.PrintOut

does not display the Print Dialog.

Also, you need to set the Background parameter to False, not True, if you
want the printing to be complete before the next line of code is executed.

--
Hope this helps,

Doug Robbins - Word MVP

Please reply only to the newsgroups unless you wish to obtain my services on
a paid professional basis.
 
J

Jonathan West

Jeff said:
Thanks For the help guys. The FSO created the folder correctly my trouble
lied in the MoveFile method. The code was trying to move the file while
still
printing.
Which brings me to another question aside from setting the Background
parameter to True in th Application.PrintOut method is there a way to
suppress the Printing Dialog box?

I presume you mean the print progress dialog which allows the user to cancel
the print job if he wants. There isn't any option within VBA to suppress
that dialog. If you are very clever with Windows API and timers, I believe
you can force the dialog to be minimised and/or hidden immediately after it
shows. If you really want to go that route, I'll leave you in the capable
hands of Karl. This is very much his area rather than mine.
 
K

Karl E. Peterson

Jonathan West formulated on Friday :
I presume you mean the print progress dialog which allows the user to cancel
the print job if he wants. There isn't any option within VBA to suppress that
dialog. If you are very clever with Windows API and timers, I believe you can
force the dialog to be minimised and/or hidden immediately after it shows. If
you really want to go that route, I'll leave you in the capable hands of
Karl. This is very much his area rather than mine.

I'm quite sure that'd be doable, yeah. It'd be very similar to
repositioning a MsgBox on demand (http://vb.mvps.org/samples/MovedMsg).
You'd just need to figure out the most basic clues about what makes
that dialog recognizable, then set a hook before allowing it to pop so
you can be alerted to take action when it does.
 

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