In a continuation of exploring working with image Exif metadata via VBA, specifically working this time with WIA, I thought I’d demonstrate how you can retrieve a single property value.
Reading A Specific Exif Property with WIA
Obviously, there are a couple of ways we could do this:
- Get the complete list of properties and their values and pull out the one we’re after
- Check if the property exists, and if it does pull just that one
Today, I’ve chosen to concentrate on the latter as it is more efficient IMHO.
The code is very simple:
'---------------------------------------------------------------------------------------
' Procedure : WIA_GetExifProperty
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website : http://www.cardaconsultants.com
' Purpose : Retrieve a specific Exif metadata property value for the specified image
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Late Binding -> None required
' Early Binding -> Microsoft Windows Image Acquisition Library vX.X
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sImage : Fully qualified path and filename of the image file to retrieve the Exif
' metadata of.
' sProperty : The property to retrieve the value of. Be careful this is case sensitive!
' EquipMake works, equipmake will not!
'
' Usage:
' ~~~~~~
' WIA_GetExifProperty("C:\Temp\Img01.jpg", "EquipModel")
' Returns -> ELE-L04
' WIA_GetExifProperty("C:\Temp\Img01.jpg", "DateTime")
' Returns -> 2021:05:08 17:01:56
' WIA_GetExifProperty("C:\Temp\Img01.jpg", "ExifVer")
' Returns -> 0210
'
' Revision History:
' Rev Date(yyyy-mm-dd) Description
' **************************************************************************************
' 1 2022-02-10 Initial Public Release
'---------------------------------------------------------------------------------------
Function WIA_GetExifProperty(sImage As String, sProperty As String)
On Error GoTo Error_Handler
#Const WIA_EarlyBind = False 'True => Early Binding / False => Late Binding
#If WIA_EarlyBind = True Then
Dim oIF As WIA.ImageFile
Dim oV As WIA.Vector
Set oIF = New WIA.ImageFile
#Else
Dim oIF As Object
Dim oV As Object
Const RationalImagePropertyType = 1006 '(&H3EE)
Set oIF = CreateObject("WIA.ImageFile")
#End If
Dim sValue As String
Dim j As Long
oIF.LoadFile sImage
If oIF.Properties.Exists(sProperty) Then
' WIA_GetExifProperty = oIF.Properties(sProperty).Value
With oIF.Properties(sProperty)
If .IsVector = False Then
If .Type = RationalImagePropertyType Then
' Debug.Print .PropertyID, .Name, GetWiaImagePropertyType(.Type), .Value.Numerator & "/" & .Value.Denominator
WIA_GetExifProperty = .Value.Numerator & "/" & .Value.Denominator
Else
' Debug.Print .PropertyID, .Name, GetWiaImagePropertyType(.Type), .Value
WIA_GetExifProperty = .Value
End If
Else
'Vector objects
Set oV = .Value
For j = 1 To oV.Count
sValue = sValue & Chr(oV.Item(j)) '& ""
Next j
sValue = Trim(sValue)
' Debug.Print .PropertyID, .Name, GetWiaImagePropertyType(.Type), sValue
WIA_GetExifProperty = sValue
End If
End With
End If
Error_Handler_Exit:
On Error Resume Next
If Not oIF Is Nothing Then Set oIF = Nothing
Exit Function
Error_Handler:
If Err.Number = -2147024894 Then
MsgBox "The specified file '" & sImage & "' does not appear to exist.", _
vbCritical Or vbOKOnly, "Operation Aborted"
Else
MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: WIA_GetExifProperty" & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occured!"
End If
Resume Error_Handler_Exit
End Function
I’ve left a few Debug.Print statements that I used while exploring all of this, that I thought might interest some of you out there. If you do use them, then you’ll also need the following helper function:
'Converts numeric Image Property Type values into English terms
Private Function GetWiaImagePropertyType(ByVal lType As Long) As String
Select Case lType
Case 1000
GetWiaImagePropertyType = "Undefined"
Case 1001
GetWiaImagePropertyType = "Byte"
Case 1002
GetWiaImagePropertyType = "String"
Case 1003
GetWiaImagePropertyType = "Unsigned Integer"
Case 1004
GetWiaImagePropertyType = "Long"
Case 1005
GetWiaImagePropertyType = "Unsigned Long"
Case 1006
GetWiaImagePropertyType = "Rational"
Case 1007
GetWiaImagePropertyType = "Unsigned Rational"
Case 1100
GetWiaImagePropertyType = "Vector Of Undefined"
Case 1101
GetWiaImagePropertyType = "Vector Of Bytes"
Case 1102
GetWiaImagePropertyType = "Vector Of Unsigned"
Case 1103
GetWiaImagePropertyType = "Vector Of Longs"
Case 1104
GetWiaImagePropertyType = "Vector Of UnsignedLongs"
Case 1105
GetWiaImagePropertyType = "Vector Of Rationals"
Case 1106
GetWiaImagePropertyType = "Vector Of Unsigned Rationals"
Case Else
GetWiaImagePropertyType = "Unknown Type"
End Select
End Function
Examples Of Its Usage
Now, with a single line of code you can retrieve a property’s value.
? WIA_GetExifProperty("C:\Temp\Img01.jpg", "EquipModel")
? WIA_GetExifProperty("C:\Temp\Img01.jpg", "EquipMake")
? WIA_GetExifProperty("C:\Temp\Img01.jpg", "ExifVer")
? WIA_GetExifProperty("C:\Temp\Img01.jpg", "DateTime")
? WIA_GetExifProperty("C:\Temp\Img01.jpg", "XResolution")
? WIA_GetExifProperty("C:\Temp\Img01.jpg", "ExifISOSpeed")
Code Features
This code
- can be used as both Early or Late Binding, the choice is yours and set by changing the value of the WIA_EarlyBind constant.
- is architecture/bitness independent (works in both 32 and 64-bit installations)
- is application independent (should work in any VBA applications – Access, Excel, Outlook, PowerPoint, Word, …)
A Few Resources on the Subject

This code is great. I tried to use it to extract GPS lat and long but I am having some issues. I was using “GpsLatitude” and “GpsLongitude” as the sProperty field but it wasn’t returning what I was expecting. If you have any tips it would be greatly appreciated. Thanks!