I am trying to make a button which will open a file on disk. But I'm doing something wrong - my code throws an error and I need help with it.
I saw this topic: Open an external file with a button on a form in Access 2007 but in that solution the first argument of this statement is the path to .exe of the program which I want to use. Problem is that I am using a company computer and I can not find NOTEPAD.EXE or Acrobat Reader 2017 (should I type another thing)?
Private Sub Polecenie45_Click()
Call Shell("""C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Acrobat Reader 2017.exe"" ""C:\Users\myusername\Desktop\p1.pdf""", vbNormalFocus)
End Sub
When I click the button I want to open my external file - for example (on this case) a pdf file with some pictures.
Iv'e found it once somewhere on the web, can't recall where. Iv'e put it in a it's own module, and use by calling OpenFile, passing in a full file path as a parameter.
Here:
Option Compare Database
Option Explicit
Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Public Function OpenFile(sFileName As String)
On Error GoTo Err_OpenFile
OpenFile = ShellExecute(Application.hWndAccessApp, "Open", sFileName, "", "C:\", 1)
Exit_OpenFile:
Exit Function
Err_OpenFile:
MsgBox Err.Number & " - " & Err.Description
Resume Exit_OpenFile
End Function
This module came with the test. you can run it:
Public Function TestOpeningFile()
On Error GoTo Err_TestOpeningFile
OpenFile "C:\Windows\Win.ini"' Replace this line with any file
Exit_TestOpeningFile:
Exit Function
Err_TestOpeningFile:
MsgBox Err.Number & " - " & Err.Description
Resume Exit_TestOpeningFile
End Function
Related
I have a table of products where there is say a pdf for a specific products user manual. I'm storing the model name and it's file path in my products table (in Access). I've created a form in Access that allows the user to search by product name and it narrows down the number of files and shows the results from the search in a list box. However my biggest problem is opening the actual PDF. It opens the file, but I have to store the file path exactly how it is and the path of the files are long. Is there a way to open the PDF hyperlinks without using the Followhyperlink command? Or is there a way that I can show only the file name of the pdf in my list box rather than the entire path name? If I change the display text in my products table it doesn't open the hyperlink, I get an error. Any help would be greatly appreciated!
Application.FollowHyperLink() has problems with security, especially when opening files on a network drive. See e.g. here: http://blogannath.blogspot.de/2011/04/microsoft-access-tips-tricks-opening.html
A better method is the ShellExecute() API function.
Essentially it looks like this (trimmed from http://access.mvps.org/access/api/api0018.htm ):
' This code was originally written by Dev Ashish.
' http://access.mvps.org/access/api/api0018.htm
Private Declare Function apiShellExecute Lib "shell32.dll" _
Alias "ShellExecuteA" _
(ByVal hwnd As Long, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long) _
As Long
Public Const WIN_NORMAL = 1 'Open Normal
Private Const ERROR_SUCCESS = 32&
Public Function fHandleFile(stFile As String) As Boolean
Dim lRet As Long
lRet = apiShellExecute(hWndAccessApp(), "Open", stFile, vbNullString, vbNullString, WIN_NORMAL)
If lRet > ERROR_SUCCESS Then
' OK
fHandleFile = True
Else
Select Case lRet
' Handle various errors
End Select
fHandleFile = False
End If
End Function
Now for your listbox:
Set it to 2 columns, the first being the model name, the second the file path.
Set the column width of the second column to 0, so it will be invisible.
And in the doubleclick event, call fHandleFile with the second column (file path):
Private Sub lstManuals_DblClick(Cancel As Integer)
Call fHandleFile(Me.lstManuals.Column(1))
End Sub
I cobbled this test procedure together in Outlook 2013 from other posts.
It should display a popup box, and then close after 3 seconds.
It never closes.
Sub MessageBoxTimer()
Dim AckTime As Integer, InfoBox As Object
Set InfoBox = CreateObject("WScript.Shell")
AckTime = 3
Select Case InfoBox.Popup("Click OK (this window closes automatically after 3 seconds).", _
AckTime, "This is your Message Box", 0)
Case 1, -1
Exit Sub
End Select
End Sub
Some research suggests that this may be a bug in some MS Office applications. I'm basing this on the fact that this and this don't seem to say anything which suggests you're using the command in the wrong way, and this shows that other users have managed to get precisely this code to work.
I tested this on my Windows PC running Excel with Office 365 and have had the same issue as you - the message box is displayed, but not closed. I found a suggested workaround here, and the discussion on that page may be of some interest to you (particularly one user's description of trying to submit a bug report to Microsoft about VBA). The solution, proposed by a user called ウィンドウズスクリプトプログラマ, is to make a call through to the native user32.dll by declaring an external function - this page has some examples of how to call C dlls with VBA.The MessageBoxTimeout function is said to be undocumented by Microsoft, but you can find out a lot about it here.
The other option, which worked for me, is run a vbscript call to Shell.Popup with mshta.exe:
Function Test()
Dim Shell
Set Shell = CreateObject("WScript.Shell")
Shell.Run "mshta.exe vbscript:close(CreateObject(""WScript.shell"").Popup(""Test"",3,""Message""))"
End Function
To get this to work with more complex messages, you may need to escape some characters. There is another SO question here which shows other uses for mshta's ability to execute vbscript in a shell/ console.
Finally, as was suggested by one user, you could simply create a custom user form with a doevents loop that counts down and then closes itself.
The WScript.Shell .Popup seems to be hit or miss in Office VBA.
If you are looking for a MsgBox that works in Office VBA and supports a timeout, I posted another method that uses a Windows API call. It supports timeout, carriage returns, and return values. You can find the code at this link. I did not think it was proper etiquette to post it again here.
Note that the mshta method mentioned by #Orphid does not support carriage returns and always shows the message on the primary monitor.
Yes, I can confirm that result: the 'Timeout' on the WsShell.Popup function is no longer working in Office.
It took me a while to notice, because popup dialogs with a 'cancel' button seem to be affected less. So this might be a usable workaround for you:
Dim msg AS String
Dim Title as String
msg ="Click 'Ok' or 'Cancel' (this window closes automatically after 3 seconds)."
Title = Application.name & ": Message Box test"
Select Case InfoBox.Popup(msg, AckTime, Title, vbQuestion + vbOkCancel)
If that doesn't work, you're going to need a much longer explanation: reimplementing the 'Timeout' using an API Timer Callback. As the author of that answer, I should warn you that this is using a sledgehammer to crack a nut after attempting the task with a prolonged naval bombardment.
I have tried the following code to control VBA msg box auto closer after 40 sec. You can try also it. It will work for you.
'The first part
#If Win64 Then '64?
Private Declare PtrSafe Function MsgBoxTimeout _
Lib "user32" _
Alias "MessageBoxTimeoutA" ( _
ByVal hwnd As LongPtr, _
ByVal lpText As String, _
ByVal lpCaption As String, _
ByVal wType As VbMsgBoxStyle, _
ByVal wlange As Long, _
ByVal dwTimeout As Long) _
As Long
#Else
Private Declare Function MsgBoxTimeout _
Lib "user32" _
Alias "MessageBoxTimeoutA" ( _
ByVal hwnd As Long, _
ByVal lpText As String, _
ByVal lpCaption As String, _
ByVal wType As VbMsgBoxStyle, _
ByVal wlange As Long, _
ByVal dwTimeout As Long) _
As Long
#End If
'The second part
Sub btnMsgbox(message As String)
Call MsgBoxTimeout(0, message, "", vbInformation, 0, 40000)
End Sub
In my VBA procedure, I need to run the app "Skitch" and use it to open a JPEG file. This is the command I've been using:
ReturnValue = Shell("C:\Program Files (x86)\Evernote\Skitch\Skitch.exe " & """" & aPic & """", 1)
...where "aPic" is the path and filename.
After some experimenting, I think I need to run the command as if it were in an Elevated Command window (in other words, run it "as Administrator"). Is it possible to run Shell elevated?
If that's not possible: If I understand correctly, using ShellExecute instead of Shell will automatically elevate the command. But I'm much less familiar with it. Can someone show me how to run my command using ShellExecute? (BTW, I know that ShellExecute is good for running commands associated with the file type, but on this user's computer *.jpg will likely not be associated with Skitch.)
Thanks.
Try this:
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" ( _
ByVal hWnd As Long, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As Long
Const SW_SHOWNORMAL = 1
Public Sub test()
ShellExecute 0, "runas", "C:\Program Files (x86)\Evernote\Skitch\Skitch.exe", aPic, vbNullString, SW_SHOWNORMAL
End Sub
I don't have skitch so can't try this, but it should work.
For more information about ShellExecute, click here to have a look on MSDN.
I want to be able to download images by using multiple image urls on vba. This is the code I have right now, and everytime I try download, it fails (It reads "Files not Found!"). Any help will be appreciated!!!
Option Explicit
Private Declare Function URLDownloadToFile Lib "urlmon" _
Alias "URLDownloadToFileA" (ByVal pCaller As Long, ByVal szURL As String, _
ByVal szFileName As String, ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
Private Sub Image()
Dim i As Long
Dim url As String
Dim done As Long
Worksheets("Sheet1").Activate
For i = 1 To 4
url = Sheet1.Range("A" & i).Text
done = URLDownloadToFile(0, url, "C:\Users\Public\Pictures\", 0, 0)
Next
'Test.
If done = 0 Then
MsgBox "Files have been downloaded!"
Else
MsgBox "Files not Found!"
End If
End Sub
I have got this code to work by doing two simple things:
Make sure you have http:// included in your urls, without the http URLDownloadToFile fails to download the file.
The usage of the URLDownloadToFile function is expecting a filename rather than a path name for the downloaded file. A quick and dirty fix is to do the following:
done = URLDownloadToFile(0, url, "C:\Users\Public\Pictures\pic" & i & ".gif", 0, 0)
which assigns a name to each file using i.
A better solution would parse the filename from the url and save using this filename.
Other than that the code worked fine for me.
I would like to launch a URL when an email arrives in Outlook. I setup a rule and have it trigger a script function. It looks like I want to call ShellExecute to launch the URL in a browser, but when I hit this line:
ShellExecute(0&, "open", URL, vbNullString, vbNullString, _
vbNormalFocus)
The method is not defined. Any ideas?
ShellExecute is a function in a windows dll.
You need to add a declaration for it like this in a VBA module:
Public Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" ( _
ByVal hWnd As Long, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As Long
The difference between your Shell solution and ShellExecute is that ShellExecute will use the default system handler for URLs to open the link. This doesn't have to be IE. Your solution will always open it in IE. Yours is the equivalent of putting iexplore.exe into the run box in windows. ShellExecute is the equivalent of just putting the url in the run box in windows.
You can also use Followhyperlink from VBA to open URLs in the default browser. It can also be used to open documents with the registered application, to send emails and to browse folders.
Alternatively, use Shell, like this:
Sub LaunchURL(Item As Outlook.MailItem)
Shell ("C:\Program Files\Internet Explorer\IEXPLORE.EXE" & " " & Item.Body)
End Sub
You can create batch file where you write this:
start http://someurl.com/?a=1^&b=2
And you configure Outlook rule to launch this batch file. Notice ^ sign before &. This is escape sequence for & in batch files. Also notice that you need to have default browser set in your Windows OS, almost 100% probability that you have it.
Shell ("CMD /C start http://www.spamcop.net"), vbNormalFocus