[German edition]Microsoft Office 2013 is shipped with new features, but some users are missing usability. For instance, a simple button to scan directly from Word 2013 is missing. Also old solutions won't work anymore. Therefore I've developed a solution, to add a scan option to Word 2013.
Anzeige
How it it shall work …
I'm using a German Word 2013, so all screenshots are made by this version. My idea was to establish a button Scan within the Word 2013 ribbon bar (Tab Insert).
Using this button invokes the dialog box shown below. A user may select the WIA device to obtain a photo.
Anzeige
After clicking OK, the WIA dialog box shown below will be visible. Here we see the scanner dialog box.
Using the Scan button obtains the scan from the connected device and inserts it into the Word document. Therefore it's required, that Windows supports WIA drivers and devices.
Implementing a macro for WIA control
How to implement this feature in Word 2013? The View tab contains the Macro button which may be used to invoke the Macros dialog box. The button create may be used to add a VBA macro.
After searching a while, I was not able to find a Word object to scan – and I wasn't successful to invoke OneNote scan button from Word. Therefore I inspected the Type-Libraries (Menu Tools, command References).
I found the "Windwos Image Acquisition Library" type library, that may be used to access the WIA interface.
VBA code to access the WIA interface
After identifying the WIA type library I made a short research and found some VBA code fragments to access WIA [1,2], deleting a file [3] and to detect the Temp folder [4] (used to store the temporary image file). Here is the VBA source code.
' Scan for Word 2013
' Author: Günter Born www.borncity.de blog.borncity.com
' Implements a Scan function in Word 2013
Private Declare Function GetTempPath Lib "kernel32" Alias "GetTempPathA" (ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
Private Function TempPath() As String
Const MaxPathLen = 256 ' Max path length
Dim FolderName As String ' Folder name
Dim ReturnVar As Long ' Return Value
FolderName = String(MaxPathLen, 0)
ReturnVar = GetTempPath(MaxPathLen, FolderName)
If ReturnVar <> 0 Then
TempPath = Left(FolderName, InStr(FolderName, Chr(0)) – 1)
Else
TempPath = vbNullString
End If
End Function
Sub Scan()
'
' Scan Macro, to be invoked in Word
'
On Error Resume Next
Dim objCommonDialog As WIA.CommonDialog
Dim objImage As WIA.ImageFile
Dim strDateiname
' instantiate Scan WIA objects
Set objCommonDialog = New WIA.CommonDialog
Set objImage = objCommonDialog.ShowAcquireImage
strDateiname = TempPath & "Scan.jpg" ' set temporary file
If Not objImage Is Nothing Then
Kill strDateiname
objImage.SaveFile strDateiname ' save into temp file
Selection.InlineShapes.AddPicture strDateiname ' insert in doc
Set objImage = Nothing
End If
Set objCommonDialog = Nothing
' MsgBox strDateiname ' test output
End Sub
The VBA code initiates a WIA.CommonDialog object and invokes the ShowAcquireImage method. The method returns the scan as an object. This will be stored temporarily and will be inserted into Word document file.
Add a scan button
At least we need to add a Scan button at Insert tab and associate it with the VBA macro.
1. Right click the ribbon bar und select the command to change ribbon settings.
2. Select the entry "macro" in the left list of dialog box Word options.
3. Add a new group entry "Scan" to Insert tab and associate the macro from left list to this new group. Name it "Scan" and assign an appropriate image to this button.
After closing the dialog box, the new Scan button shall be working. Here is a download file Scan1.zip, containing a Word *.docm file and a macro code file (.bas) with a a ready to use solution. You may use the sample and copy the macro code to your Normal.dot file.
Links:
1: Technet-Article
2: Scan in Access
3: Delete files in VBA
4: Detect temp folder
Anzeige
It seems that the VBA-code shown above causes a few pitfalls. Therefore a short brush-up.
Macro security prevents VBA code execution?
If the macro is blocked due to the VBA security settings, select the FILE tab in ribbon bar and click the Options-command in backstage.
Select Trust Center in Word options and click the button Trust Center settings. Change the options in a proper way to allow VBA macro execution.
Reference to type library is mandatory
Also be sure, to select "Tools -> References" and assure, that the "Windows Image Acquistion Library" (WIA type library) is included (the check box must be checked) within the project.
I will try to implement a separate solution with late binding (see here) to avoid the need to set references in Tools-Menu.
Windows 64 Bit
Also the macro code shown above won't run in a 64-Bit-Environment. An error message as shown below will occur.
Well, I've developed and testet the solution in a virtual machine under 32-Bit-Windows 8 with Office 2013. Obviously the API-call to obtain the temp folder fails in a 64-Bit-Office-Environment. It's sufficient to change the API declaration [a3] from:
Private Declare Function GetTempPath Lib "kernel32" _
Alias "GetTempPathA" (ByVal nBufferLength As Long, _
ByVal lpBuffer As String) As Long
to:
Private Declare PtrSafe Function GetTempPath Lib "kernel32" _
Alias "GetTempPathA" (ByVal nBufferLength As longptr, _
ByVal lpbuffer As String) As Long
If that doesn't help in a 64-bit-environment, please use the VBA code below for a quick and dirty workround.
' Scan for Word 2013
' Author: Günter Born http://www.borncity.de blog.borncity.com
' Implements a Scan function in Word 2013
Sub Scan()
'
' Scan Macro, to be invoked in Word
'
On Error Resume Next
Dim objCommonDialog As WIA.CommonDialog
Dim objImage As WIA.ImageFile
Dim strDateiname
' instantiate Scan WIA objects
Set objCommonDialog = New WIA.CommonDialog
Set objImage = objCommonDialog.ShowAcquireImage
strDateiname = "C:UsersPublicPictures" & "Scan.jpg" ' set temporary file
If Not objImage Is Nothing Then
Kill strDateiname
objImage.SaveFile strDateiname ' save into temp file
Selection.InlineShapes.AddPicture strDateiname ' insert in doc
Set objImage = Nothing
End If
Set objCommonDialog = Nothing
' MsgBox strDateiname ' test output
End Sub
I've removed the function to obtain the temp folder path. The image file will be saved to C:UsersPublicPictures (so it's mandatory, that Windows is installed on drive C:.
Hope that helps.
Links:
a1: Walkthrough: Calling Windows APIs (Visual Basic)
a2: Kompatibilität 32-/64-Bit-Version von Office 2010
a3: Declaring API Functions In 64 Bit Office
a4: Office 64bit VBA und Windows API
a5: A Graphic Discussion about the Windows Image Acquisition Component
a6: Shared Samples (Windows)
Addenum: Some readers reported problems with the macro code obtained via copy & paste. Therefor I've uploaded a ZIP archive scanBas.zip, containing two .BAS modules (that implements two versions of the macro code).
You can use File -> Import file in VBA editor to import the content of a BAS module. All VBA lines shall be colored green, blue or black, but not read. In this case, the VBA modules should compile successful.
Good luck
Excellent using the scanBas.zip import file worked perfectly on my 64bit system
Many Thanks, it is perfect whith scanBas.zip imported
Alain (FRANCE)
Danke, danke, danke!!!
Fantastische Arbeit!
Do you think this will work in the USA English version of MS Office 2013?
How about Office 365 or Office on Demand?
Thank you.
The macro itself should work in English language version. Also Office 365 should work, if the requirements are given (WIA enabled driver, Type libraries in VBA activated).
Hi, I 've tried using your code to scan , import the macros have to download , but the macro runs without showing me anything, thanks in advance for your attention and your knowledge , thanks
Greetings from Veracruz Mexico
@Eder: Then something went wrong. Either your WIA drivers are non functional – or (more probable), you have made an error typing the source code. One reader reported a similar flaw (preview was functional, but scanning doesn't delivered anything). The cause was a wrong quotation for strings within the VBA source code. In the readers case he used a wrong quotation for a path, defining the location of temporary files. So, pls double and triple check the code. You are also able to debug the VBA code and have a look what's turned back from calling the scan method.
HTH
Dear Mr. Günter:
Its development is superb and will communicate that works in Office 2013 in Spanish (at least in Spain). Just have to make a slight change in characters (ex. the comma ') that are not interpreted well in the original. For if it is of interest, I step adapted to Spanish code:
' Scan for Word 2013
' Author: Günter Born http://www.borncity.de blog.borncity.com
' Implements a Scan function in Word 2013
Private Declare Function GetTempPath Lib "kernel32" Alias "GetTempPathA" (ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
Private Function TempPath() As String
Const MaxPathLen = 256 ' Max path length
Dim FolderName As String ' Folder name
Dim ReturnVar As Long ' Return Value
FolderName = String(MaxPathLen, 0)
ReturnVar = GetTempPath(MaxPathLen, FolderName)
If ReturnVar 0 Then
TempPath = Left(FolderName, InStr(FolderName, Chr(0)) – 1)
Else
TempPath = vbNullString
End If
End Function
Sub Scan()
'
' Scan Macro, to be invoked in Word
'
On Error Resume Next
Dim objCommonDialog As WIA.CommonDialog
Dim objImage As WIA.ImageFile
Dim strDateiname
' instantiate Scan WIA objects
Set objCommonDialog = New WIA.CommonDialog
Set objImage = objCommonDialog.ShowAcquireImage
strDateiname = TempPath & "Scan.jpg" ' set temporary file
If Not objImage Is Nothing Then
Kill strDateiname
objImage.SaveFile strDateiname ' save into temp file
Selection.InlineShapes.AddPicture strDateiname ' insert in doc
Set objImage = Nothing
End If
Set objCommonDialog = Nothing
'MsgBox strDateiname 'test output
End Sub
Thank You from Barcelona
Ramon Díez
I want to clarify what I mean straight we have in the Spanish keyboard to the point, which is just below the question mark (?). Apparently, for reasons of language, although I insert the code with "our" coma, it is reconverted to eat employing Günter. Thank you all. I repite in spanish:
Quiero aclarar que me refiero a la coma recta que tenemos en el teclado español, que se encuentra justo debajo del interrogante de cierre (?). Al parecer, por razones de idioma, aunque yo inserte el código con "nuestra" coma, se reconvierte a la coma que emplea Günter. Gracias a todos.
I HAVE INSTALLED YOUR 64 BIT SCANNER CODE BUT GET ERROR MESSAGE
AS OBJECT NOT DEFINED FOR LINE
Dim objCommonDialog As WIA.CommonDialog
I AM USING WIN 7 OFFICE word 2013
MANY THANKS
It seems that the reference to WIA library is missing. See also
How to add a scan function to Word 2013
Scanning in Word 2013/2016 – Part I
I HAVE INSTALLED YOUR 64 BIT SCANNER CODE BUT GET ERROR MESSAGE
AS OBJECT NOT DEFINED FOR LINE
Dim objCommonDialog As WIA.CommonDialog
I AM USING WIN 7 OFFICE word 2013
MANY THANKS
FIXED _ MICROSOFT WINDOWS IMAGE ACQUISITION WAS NOT TICKED
Again lovely macro – Many thanks
Another issue – please help
Your macro works when option for flatbed is selected.
For option Document feeder – error message …another scanner is working …..
Thanks
Fear I can't help – it seems that Document feeder isn't supported from WIA.
Could you break this out a lot more; for someone that has zero VBA or Macro creating skills?
I just want to be able to use my scanner in Word 2013
Unfortunately the bozos at Micro$oft don't take the end users into consideration ever.
Thank you for this brilliant solution Mr Günter!
Do you think this would also work on Win7 PC with Office 2016?
Danke im Voraus,
Márk
Scanning in Word 2013/2016 – Part I