Digital Camera access using VBA

I have a manufacturing company that uses digital cameras to take pictures of the parts and my Access Database is responsible for the acquisition and saving of such images.  It used to be any easy affair as cameras always installed themselves as drives on USB plug-in, therefore I  I would:

1) Have the software check all drives available (a-z) for any drives that had a folder title "DCIM" which is the folder almost all cameras store pictures in.
2) I would then List those directories with a list box
3) Then I have the software do stuff with the file

But lately all the cheap cameras I am buying are now installing themselves as devices instead of drives.  I therefore don't know how to access them generically.  I don't want to key in on a specific name (in this case the device name is S3700) because I have to be able to use different cameras without changing any programming and table fields.

1) Please don't suggest a card reader. This is an extra step that, in a manufacturing setting, will add too much complication.

How do I generically call/search for devices that are cameras and then check directories on such devices!  NOTE:  In this case, the device (S3700) still has a directory "DCIM" on it.  Let's assume that all cameras still operate this way in that they still have a main folder title "DCIM".

I have tried:

1) Drive Management - Camera does not appear as a hard drive and thus a drive letter cannot be assigned/mapped.
jparisoAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jparisoAuthor Commented:
Here is a jpg of windows explorer for reference as to how it is installing itself, not it is not a drive or drive letter.Explorer.JPG
Boyd (HiTechCoach) Trimmell, Microsoft Access MVPDesigner and DeveloperCommented:
But lately all the cheap cameras I am buying are now installing themselves as devices instead of drives.
I don't think it has anything to do with being cheap. I have expensive devices that do the same thing.


I have used WMI to get all USB devices. This should get you started:

NOTE: You must set a reference to the Microsoft WMI Scripting V1.2 Library
 
the 
Sub RetrieveUSBInfo()

    '--------------------------------------------------------------------------------------------------
    'Loops through all the USB controllers and devices (sticks, hubs, etc.) and retrieves information.
    'The code uses a WMI script in order to access the Win32_USBControllerDevice class.
           
   
    'Declaring the necessary variables.
    Dim strComputer     As String
    Dim strDeviceName   As String
    Dim objWMIService   As Object
    Dim colControllers  As Object
    Dim objController   As Object
    Dim colUSBDevices   As Object
    Dim objUSBDevice    As Object
    Dim i               As Integer
    
    'Just in case of an error...
    On Error Resume Next
    
     
    'Set the computer.
    strComputer = "."
    
    'The root\cimv2 namespace is used to access the Win32_USBControllerDevice class.
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    
    'A select query is used to get the list of all USB controllers.
    Set colControllers = objWMIService.ExecQuery("Select * From Win32_USBControllerDevice")
    
    'Start below sheet headings.
    i = 2
    
    'Loop through all the collection of USB controllers.
    For Each objController In colControllers
       
       'Retrieve the device name from the controller.
       strDeviceName = Replace(objController.Dependent, Chr(34), "")

       strDeviceName = Right(strDeviceName, Len(strDeviceName) - InStr(strDeviceName, "="))
       
       
       'Execute a select query on Win32_PnPEntity class based on device name.
       Set colUSBDevices = objWMIService.ExecQuery("Select * From Win32_PnPEntity Where DeviceID = '" & strDeviceName & "'")
       
       'Loop through all the USB devices and write the necessary data in the sheet.
       For Each objUSBDevice In colUSBDevices
           
                Debug.Print objUSBDevice.Name
                Debug.Print objUSBDevice.Manufacturer
                Debug.Print objUSBDevice.Status
                Debug.Print objUSBDevice.Service
                Debug.Print objUSBDevice.DeviceID
                Debug.Print "--------------------------------------------"
          ' 
            i = i + 1
        Next
    Next
    
End Sub

Open in new window


Adapted to Access VBA from Excel code found here:
http://www.myengineeringworld.net/2014/01/retrieve-usb-device-information-vba-wmi.html
jparisoAuthor Commented:
Thanks for the quick response.

I see what you are doing here, that library is a new one for me.  I'll enable it and play around with the code and see if I can get it to work with my project.  I'll post back with feedback either way...
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

jparisoAuthor Commented:
I'm having some trouble with the application of this code.

The code is indeed outputting all the USB devices, no problem there.  But I am having trouble using the device name to verify the existence of the folder DCIM on that device. I am presently using code like this:

IF Dir(strTemp & ":\DCIM", vbDirectory) <> "" then
        Stuff...
End IF

Open in new window


However when I try to use the usb device name in this scheme (i.e. S3700) it doesn't work (See attached image)Capture.JPG
Chuck LoweCommented:
@jpariso . Hey did you ever get an answer to this? I'm trying to do the same thing.
I find alot more about it on the web so I may arrive at an answer myself and share it with the group.

This link shows alot of what is returned for usb devices. It actually has more than what I found on the msdn site

http://stackoverflow.com/questions/30337779/detect-usb-device-upon-plugged-in-and-get-its-wmi-information-in-vb 

here is the msdn site for WMI for (I'm guessing) everything on a computer.

https://msdn.microsoft.com/en-us/library/aa394587(v=vs.85).aspx
Boyd (HiTechCoach) Trimmell, Microsoft Access MVPDesigner and DeveloperCommented:
jpariso,

The code works to get you the device name using WMI.

Sounds like the issue you are having now is once you get the device name is how to create a path to a folder on the device?
jparisoAuthor Commented:
@Boyd

Yes that is correct, your code works fine to get the device name. No problem there.

I am not sure how to reference (what seems like a folder) on the usb camera name "DCIM" using the said device name.

(As a side note, your code returned 15 or so USB devices, many of which are not USB drive type devices.  I figured I'd just loop through each usb device and check for the folder named DCIM and then list any USB device that contain that folder, but I am having trouble referencing the path, like you said.)
jparisoAuthor Commented:
@ Chuck

Thanks. I checked out those two links, I see lots there similar to what Boyd provided, but I don't see anything in terms how to reference the path of USB devices that behave like drives.
Boyd (HiTechCoach) Trimmell, Microsoft Access MVPDesigner and DeveloperCommented:
@jpariso,

I have a growing need to do the same thing. SO I am very curios to see this work.

I have spent the last several hours working with File System Objects, WIA, VBA, and Powershell with no luck.

I have learned that devices that are compatible with Device Stage are seen by Windows as potable devices. This the a new Windows standard appears to not be fully baked.

I am trying to figure out what Windows File Explorer uses.
jparisoAuthor Commented:
The plot thickens...

I don't claim to have as much knowledge as you, but just the fact that windows explorer changes, inserts in front of, and refers to "This PC" after clicking in the path box in windows explorer (i.e. "This PC\S3700\S3700\DCIM") seemed very strange to me as "This PC" is not a normal directory I'm aware of.

I didn't go the powershell route but figured it would have the same issue... it's got to be a path syntax problem, you would think.
Chuck LoweCommented:
@ jpariso
 Sure thing. I do have code somewhere that will only return the usb device only if something is connected to it. Posting with my phone now so I'll dig it up and send tomorrow from the office. I'll also have some time to research finding folders once I find the camera connected . I'm sure all this combined cortex power will be able to solve it.
jparisoAuthor Commented:
But you are right, what exactly is explorer using, it obviously treats the device the same way it would treat a drive...
jparisoAuthor Commented:
with Device Stage are seen by Windows as potable devices

Did you mean to say potable... or is it portable???
jparisoAuthor Commented:
must likely what you see is a shell namespace extension view that does not have a physical folder. If you don't see it in file dialogs, then it does not support Windows's file dialogs, so you can not access the shell namespace extension view in programs other than Windows Explorer.

Does this quote have relevance?   Taken from this discussion below...

https://social.msdn.microsoft.com/forums/windowsdesktop/en-us/0443c1f6-b3ef-44d1-b7f1-6f2e9b49e335/path-to-portable-device
jparisoAuthor Commented:
If the camera is recognized by Windows Vista/7 as a "Portable Device", you can probably use Windows Portable Device APIs to enumerate/transfer files from the device.

https://msdn.microsoft.com/en-us/library/dd388996%28v=VS.85%29.aspx

Also from the discussion posted above... maybe we can use this API?
Boyd (HiTechCoach) Trimmell, Microsoft Access MVPDesigner and DeveloperCommented:
Yes. I meant Windows as portable devices. I was not fastest enough to edit it before you posted your reply.

The link you posted is the exact issue I have been seeing. I do now it is possible because I use several programs that can see my portable devices and retrieve the files. The camera manufactures have software that will do it.

@Chuck,  we can get the USB devices without any issue. That is the easy part.  It is taking the USB information that is returned and using it to build a full folder path the the device that is not working.

File Explorer uses This PC\device_name.  We can use the code I posted to get the device_name.  What we have not figured out is how to substitute This PC to get the the full path that can be used outside of File Explorer.
jparisoAuthor Commented:
Yes, we agree it's possible.

I'm quickly getting out of my league here but...

https://msdn.microsoft.com/en-us/library/dd319330%28v=vs.85%29.aspx

It appears folders on such devices are objects that need enumeration?
Boyd (HiTechCoach) Trimmell, Microsoft Access MVPDesigner and DeveloperCommented:
jpariso,

I think you may have found the path that leads to a  solution. That link looks very promising. I am looking into it now.
jparisoAuthor Commented:
It's all you at this point, I generally know where you are going to have to go with this.  I can't imagine iterating through all the objects is going to be fun coding.  I can't believe they made it this hard to grab files from a non-explorer environment.

Like I'm the first person that is going to need to easily grab files off a camera using vba, powershell etc.  Their solution is to force us to write our own file explorer code to do something that has been easily accomplished for decades without ridiculous amount of special code... this is an improvement how exactly?

Anyway, done with the rant... hope you're successful!
Boyd (HiTechCoach) Trimmell, Microsoft Access MVPDesigner and DeveloperCommented:
jpariso, I get the rant. You are not along .

I hae not forgot you.I am still workng on a solution.
jparisoAuthor Commented:
Thanks,

It is on my mind but I know what the issue is here and know it is going to take some time considering what the solution is.  I wasn't even going to comment here until at least a week passed by, and even then it would only be for status.  No worries.
Chuck LoweCommented:
There may be of some help. There is a thread under this topic "MS Access 2010 capture image" which references vba code in access.

I am not able to make it run since I'm a contractor with locked down ability so I will try it at home. You may need to add a Reference under tools and some other settings. Anyway there are references to vba code and MSDN on WIA (Windows Image Aquisition).

You'll see how the code for the dialog box is a little different.

Credit goes to telyni19 who posted the info. So no points for me.

Let us know if you're successful and I'll do the same.
jparisoAuthor Commented:
@Chuck

Thanks, this looks like some promising links... I think.

@BOyd

http://www.experts-exchange.com/Database/MS_Access/Q_28114061.html

The link above is what Chuck is referencing. Below is the response from telyni19.  I'm not sure telyni19 has everything there, especially because it looks like maybe they are actually trying to command the device to "capture" an image instead just plain listing and moving picture files. But if you click on some of telyni19 links, some of the code you need may be in there from what I can gather by looking at the code examples...

In theory, this should be possible. For instance, Microsoft supports development for WIA - windows image acquisition, which allows interaction with devices like cameras and scanners and such. The trick is making that connection between your application and the device. Once the application acquires the image, it'd be simple enough to add the filename to a table and store the image in a directory.

Here's a thread on capturing images into Access from a USB camera, with some sample VBA code:
http://bytes.com/topic/access/answers/931097-wia-image-capture-windows-7-a

MSDN reference on WIA:
http://msdn.microsoft.com/en-us/library/ms630827%28v=vs.85%29.aspx

Thread on capturing images from a webcam using vb.net:
http://www.vbforums.com/showthread.php?378126-WIA-%28Windows-Image-Acquisition%29-WebCam-Sample-Project

Alternately, here's a commercial tool which sounds relevant:
http://www.remote-scan.com/share-camera.php
"RemoteScan ShareCamera™ is a software solution that makes it easy to use digital cameras and other digital imaging devices in Terminal Services or Citrix environments."
Boyd (HiTechCoach) Trimmell, Microsoft Access MVPDesigner and DeveloperCommented:
Yes, I use WIA to get an image from scanners and take pictures with a camera/web cam. I have not seen any way to use it to read the storage on any portable device. I will takje another look to see if this has been added.

I will check out your links.
Boyd (HiTechCoach) Trimmell, Microsoft Access MVPDesigner and DeveloperCommented:
There is a solution that requires you to make a setting change in the device manager. You can change the device to use MSC mode instead of the default MTP. Then it will assign a drive letter.

For me this is not the ideal solution because end users shouldn't have to do this.

I am making great progress. For anyone reading this check out: http://blogs.msdn.com/b/wpdblog/rss.aspx
jparisoAuthor Commented:
@Boyd

Agreed.  We shouldn't have to do a lot of things we have to do to make things work!  I'm on the fence on this one.  Since your working on the code, I will wait to see what develops of that.  That is a more fool proof way to attack this problem so it is solved no matter what camera is used.
Chuck LoweCommented:
@All
I'll see if I get anywhere this weekend also . This is something I need to.
Boyd (HiTechCoach) Trimmell, Microsoft Access MVPDesigner and DeveloperCommented:
@All,

I figured out there was a Picture transfer protocol (PTP). It is also possible to map PTP Objects to WIA Items

Looks like WIA may be able to do the job!

That lead me to this example app:  http://www.codeproject.com/Articles/30726/Transferring-D-images-with-WIA

Have not tried the above example but it sounds like concept should  be possible with WIA.

This may also be of interest:

https://msdn.microsoft.com/en-us/library/dd389005%28VS.85%29.aspx
jparisoAuthor Commented:
Very interesting... I am going to try to fiddle with that code today!
Nick67Commented:
It's a PITA that very, very few cameras report as mass storage devices any more.
It make what you want to do -- and what we do -- much more difficult in a VBA environment.
Boyd has pointed you at WIA, and that is indeed what I use.
The WIA dialog window comes in a predetermined size with a default item selected and cannot be manipulated by VBA in-line, as the VBA pauses while that dialog exists

Pity.

So I built the WIA code as VBScript and use VBA to call the script -- then I try to deselect the item and resize via WInAPI.
I also resize to 1600 x 1200 on the fly.

After the script creates the files in a place where my friend FileSystemObject can find them, I use VBA for creating records of the paths in a table.

Please find below the VBScript for using WIA to allow the user to select pictures to be copied from various Canon- and HP-branded cameras.  Read my articles for more discussions of the use of WIA

Main()

'-------------------------------------------------------------------------------------------------------------------------------------------
Sub Main()

call GetFromCameraDevice()

end sub


Private Function GetFromCameraDevice()
On error resume next
'ok I want to get a camera and select some images from it

Dim i 'As Integer
Dim dev 'As WIA.Device
Dim itms 'As WIA.Items
Dim itm 'As WIA.Item
Dim img 'As WIA.ImageFile
Dim s 'As String
Dim BuiltPath 'As String
Dim x 'As Integer
Dim wait 'As Double
Dim success 'As Boolean
Dim myDialogIsOpen 'As Boolean
Dim ConfirmString 'As String
Dim myJobID 'As Long
dim devName
Dim DM 'As DeviceManager
Set DM = CreateObject("WIA.DeviceManager")

Dim CD 'As CommonDialog
Set CD = CreateObject("WIA.CommonDialog")

Dim IP 'As ImageProcess
Set IP = CreateObject("WIA.ImageProcess")
IP.Filters.Add IP.FilterInfos("Scale").FilterID
IP.Filters(1).Properties("MaximumWidth") = 1600
IP.Filters(1).Properties("MaximumHeight") = 1200
            
Dim fs 'As Object
Set fs = CreateObject("Scripting.FileSystemObject")

For i = 1 To DM.DeviceInfos.count 'run through the devices in a loop
   Set dev = DM.DeviceInfos(i).Connect ' connect to it 
 	'msgbox  
	devname = dev.Properties("Name").Value

      if instr(devname, "canon") <> 0 and dev.type = 2 then 'its a canon camera
	    exit for
      end if

 
      if instr(devname, "HP") <> 0 and dev.type = 2 then
	    exit for
       end if
next




if not (instr(devname, "HP") <> 0 or instr(devname, "canon") <> 0) then
    exit function
end if

        Set itms = CD.ShowSelectItems(dev, ColorIntent, MaximizeQuality, False, True, true)
	if err.number =  -2145320860 then
		msgbox "nothing selected"
		exit function
	end if

	msgbox "got here"

        BuiltPath = "c:\temppdf\"
        For Each itm In itms
            Set img = itm.Transfer 'transfers the picture from the camera to an object that can be processed or saved
            'now check if it's wider than 1600 pixels
            s = BuiltPath & itm.Properties("Item Name").Value & ".jpg"
            If img.Width < 1601 Then 'small enough, just save
                img.SaveFile (s) ' saves the raw image to a fully qualified filename, some parts I may need to pass into this function
            Else
                ' deal with stupidly large pictures
                If fs.FolderExists(BuiltPath & "large\") = False Then
                    fs.CreateFolder BuiltPath & "large\"
                End If
                s = BuiltPath & "large\" & itm.Properties("Item Name").Value & ".jpg"
                img.SaveFile (s)
    
    
                Set img = IP.Apply(img)
                s = BuiltPath & itm.Properties("Item Name").Value & ".jpg"
                img.SaveFile (s)
            End If
            'image saved

            x = 1
    
            Do Until success = True
                success = fs.FileExists(s) Or x = 3
                If success = False Then
                    wait = Timer
                    While Timer < wait + 1
                       DoEvents  'do nothing
                    Wend
                    success = fs.FileExists(s)
                    x = x + 1
                End If
            Loop
            If success = True Then
                If Nz(ConfirmString, "") = "" Then
                    ConfirmString = itm.Properties("Item Name").Value & ".jpg"
                Else
                    ConfirmString = ConfirmString & vbCrLf & itm.Properties("Item Name").Value & ".jpg"
                End If
                'MsgBox PicFileName & " transferred successfully!"
    
            Else
                MsgBox "The transfer of " & itm.Properties("Item Name").Value & ".jpg" & " failed"
            End If

        Next


End Function

Open in new window


I have remote users that use the following VBScript below to use WIA to get photos off a camera, into a local folder, and then copied to a remote server folder

   'declare an object to be a filesystem object
Public fs
  'declare an object to be a MS Access application
Public acApp
   'declare a wscript shell
Public WshShell
   'declare a filedialog object
Public fd
public shell

Public myDrives
Public myDrive
Public MyInitialFileName
Public MyComputerName

Main()

'-------------------------------------------------------------------------------------------------------------------------------------------
Sub Main()

Set fs = CreateObject("Scripting.FileSystemObject")
'get access running and open a filedialog
Set acApp=CreateObject("Access.Application")
Set fd = acApp.FileDialog(3)'msoFileDialogFilePicker

MyComputerName = GetMyComputerName

if CopyFromCamera = "Success" then
	msgbox "Transferred from camera..now transfering to server.... 2-5 minutes"
	if CopyToRDP = "Success" then
	    CleanUpLocal
	end if
end if

end sub

'---------------------------------------------

Private Function CopyFromCamera()

Dim x
Dim BuiltPath
Dim PicFileName
Dim MyInitialFileName
Dim response
Dim vrtSelectedItem

MyInitialFileName =  FDInitialFilename()

if MyInitialFileName = "WIACamera" Then
    copyFromCamera = GetFromCameraDevice
    exit function
end if


With fd
    .AllowMultiSelect = True
    .InitialView = 5 'msoFileDialogViewThumbnail
    .Title = "Picture Selector"
    .InitialFileName = FDInitialFilename()
    .ButtonName = "Xfer and Save"

    If .Show = True Then
        response = MsgBox("If you continue, the files you just selected will be copied to the temporary folder.", vbyesno, "Transfer and Save")
        If response = vbYes Then
            'create a folder to save pictures to
            BuiltPath = "c:\tempPDF\"
                

            If fs.FolderExists(BuiltPath) = False Then
                msgbox "The folder 'C:\tempPDF' doesn't exist, and this script cannot create it.  Do so manually and try again."
		CopyFromCamera = "failed"
		exit function
            End If

            For Each vrtSelectedItem In .SelectedItems
                fs.CopyFile vrtSelectedItem, BuiltPath
            Next 'vrtSelectedItem
               
        Else
	    CopyFromCamera = "failed"
            Exit function

        End If
    Else
	CopyFromCamera = "failed"
        Exit function       
    End If

End With

CopyFromCamera = "Success"

End Function

'----------------------------------------------------------

Private Function FDInitialFilename()
if FDInitialDriveName  = "ActiveCameraDeviceOnly" then 'gotta canon

    FDInitialFilename = "WIACamera"
    exit function
end if

if FDInitialDriveName <> "" then
    FDInitialFilename = FDInitialDriveName & ":\DCIM"
    exit function
end if


End Function

'----------------------------------------------------------

Private Function FDInitialDriveName()
on error resume next
Set myDrives = fs.Drives

For Each myDrive In myDrives

    If myDrive.DriveLetter <> "A" and myDrive.DriveLetter <> "C" Then     
        If fs.FolderExists(myDrive.DriveLetter & ":\DCIM") Then
            FDInitialDrivename = mydrive.driveletter
            exit function
        end if
    End If

Next


'we may have a canon camera

Dim dev
Dim DM
Dim i


Set DM = CreateObject("WIA.DeviceManager")


For i = 1 To DM.DeviceInfos.count 'run through the devices in a loop
    Set dev = DM.DeviceInfos(i).Connect ' connect to it

    If dev.Type = CameraDeviceType And (dev.Properties("Name").Value Like "canon*" Or dev.Properties("Name").Value Like "HP*") Then ' if its a canon camera
	FDInitialDriveName = "ActiveCameraDeviceOnly"
        Exit Function
    End If
Next


MsgBox "The camera might not be properly plugged in"
FDInitialDriveName=""
    


End Function

'----------------------------------------------------------


Private function CopyToRDP

Dim BuiltPath
dim serverpath
dim myfiles
dim myfolder
dim myfile
dim myMsg

BuiltPath = "c:\tempPDF\"
serverpath = "\\myserver\tempPics\"                

If fs.FolderExists(BuiltPath) = False Then
    msgbox "The local folder 'C:\tempPDF' doesn't exist, and this script cannot create it.  Do so manually and try again."
    CopyToRDP = "failed"
    exit function
else
'msgbox "local"
End If


If fs.FolderExists(serverpath) = False Then
    msgbox "The server folder '\\myserver\tempPics' doesn't exist, and this script cannot create it.  Call Nick."
    CopyToRDP = "failed"
    exit function
else
'msgbox "server"
End If


If fs.FolderExists(serverpath & MyComputerName & "\") = False Then
   fs.CreateFolder(serverpath & MyComputerName & "\") 
End If



If fs.FolderExists(serverpath & MyComputerName & "\" & day(date()) & "-" & month(date()) & "-" & year(date()) & "\") = False Then
   fs.CreateFolder(serverpath & MyComputerName & "\" & day(date()) & "-" & month(date()) & "-" & year(date()) & "\")  
End If

serverpath = serverpath & MyComputerName & "\" & day(date()) & "-" & month(date()) & "-" & year(date()) & "\"


' ok I have a server and local path
set myfolder = fs.getfolder(builtpath)
set myfiles = myfolder.files


myMsg = "The following files are on the server:"


For Each myfile In myfiles
	myMsg= myMsg & vbcrlf &  myfile.name
    fs.CopyFile builtpath & myfile.name, serverpath
Next

msgbox mymsg

' Create Windows shell Application object.
Set Shell = WScript.CreateObject ("Shell.Application")
shell.open serverpath

CopyToRDP = "Success"

end function


'-----------------------------------------------------------------------------
sub CleanUpLocal
Dim BuiltPath
dim serverpath
dim myfiles
dim myfolder
dim myfile
dim myMsg


BuiltPath = "c:\tempPDF\"

' ok I have a local path
set myfolder = fs.getfolder(builtpath)
set myfiles = myfolder.files


myMsg = "The following files were cleaned up locally:"


For Each myfile In myfiles
	myMsg= myMsg & vbcrlf &  myfile.name
    fs.deleteFile builtpath & myfile.name, true
Next

msgbox mymsg


end sub

'--------------------------------------------------------------------



Private Function GetMyComputerName
Set wshShell = WScript.CreateObject( "WScript.Shell" )
GetMyComputerName = wshShell.ExpandEnvironmentStrings( "%COMPUTERNAME%" )

end function

'---------------------------------------------------------------------


Private Function GetFromCameraDevice()
On error resume next
'ok I want to get a camera and select some images from it
'As this is vbcript, you can't declare types, so those have been commented out

Dim i 'As Integer ' a counter for any WIA device seen by the system as I loop through them
Dim dev 'As WIA.Device
Dim itms 'As WIA.Items
Dim itm 'As WIA.Item
Dim img 'As WIA.ImageFile

Dim s 'As String ' a variable to hold the full filename of the images that will be saved
Dim BuiltPath 'As String '

Dim x 'As Integer 'used in delay loops
Dim wait 'As Double
Dim success 'As Boolean
Dim response
dim var1
dim var2

var2 = "Canon PowerShot A1400"


Dim devName
Dim DM 'As DeviceManager
Set DM = CreateObject("WIA.DeviceManager")

Dim CD 'As CommonDialog
Set CD = CreateObject("WIA.CommonDialog")

Dim IP 'As ImageProcess
Set IP = CreateObject("WIA.ImageProcess")
IP.Filters.Add IP.FilterInfos("Scale").FilterID
IP.Filters(1).Properties("MaximumWidth") = 1600
IP.Filters(1).Properties("MaximumHeight") = 1200
            

Dim fs 'As Object
Set fs = CreateObject("Scripting.FileSystemObject")

For i = 1 To DM.DeviceInfos.count 'run through the devices in a loop
    Set dev = DM.DeviceInfos(i).Connect ' connect to it
    devName = dev.Properties("Name").Value
    If devName = var2 then
	Exit For
    End If
next


'***Note***
'it might have been more elegant to pass it the full device name as another argument
'I could have the VBA code determine the camera from a table, rather than hard coding the values
'As I have only one production model that this code deals with
'I haven't done so at this time
'But Now I did it


if devName <> var2 then
    msgbox devname
    exit function 'Didn't find a camera
end if


'ok, the next line creates the dialog box that the VBA code is then going to act on

Set itms = CD.ShowSelectItems(dev, ColorIntent, MaximizeQuality, False, True, True)

If Err.Number = -2145320860 Then  'the error thrown when cancel or close is hit, instead of selecting an item
    MsgBox "You exited without selecting anything from the " & devname
    GetFromCameraDevice = "Failure"    
Exit Function
End If


response = MsgBox("If you continue, the files you just selected will be copied to the temporary folder.", vbyesno, "Transfer and Save")
If response = vbYes Then
    'create a folder to save pictures to
    BuiltPath = "c:\tempPDF\"              
    If fs.FolderExists(BuiltPath) = False Then
        msgbox "The folder 'C:\tempPDF' doesn't exist, and this script cannot create it.  Do so manually and try again."
	GetFromCameraDevice = "Failure"
	exit function
    End If

    For Each itm In itms
        Set img = itm.Transfer 'transfers the picture from the camera to an object that can be processed or saved
        s = BuiltPath & itm.Properties("Item Name").Value & ".jpg"
        img.SaveFile (s) ' saves the raw image to a fully qualified filename, some parts I may need to pass into this function
    Next
    GetFromCameraDevice = "Success"
else
    GetFromCameraDevice = "Failure"
end if

End Function

Open in new window


I curse the fact that cameras no longer report as mass storage devices -- but we deal with it.

Now, the fact that Canon no longer makes cheap cameras with mini-USB plug-ins that take AA batteries is the serous problem.

Hope this helps.

Nick67
Boyd (HiTechCoach) Trimmell, Microsoft Access MVPDesigner and DeveloperCommented:
@Nick67,


Thanks for the code. Looks great great. I will test it out tonight.

It's a PITA that very, very few cameras report as mass storage devices any more.
...

 I curse the fact that cameras no longer report as mass storage devices -- but we deal with it.

For my DLR camera  i went into the device manage and changed the type so it now gets a drive letter automatically.  I changed the device to use MSC mode instead of the default MTP.
Chuck LoweCommented:
I'm getting "Variable not defined" on Colorintent in code -

Set itms = CD.ShowSelectItems(dev, ColorIntent, MaximizeQuality, False, True, True)

I added the Reference  Microsoft WMI Scripting V1.2 Library
jparisoAuthor Commented:
@Nick67   Thanks for the added clarifications and posting.  It now is getting even more complicated, the fact that we have to call out VBScript from VBA.  I'm now leaning toward just adjusting it in device manager.

@Boyd  Can you describe further how you did the mod in device manager.

I see my camera in device manager under "Portable Devices", but I am unsure where to go from there in the properties setting... I've been struggling with all this WIA stuff a little bit and now just want to set the darn thing the way it should be in the device manager!!!!
Nick67Commented:
You don't have to use VBScript.
I happen to use that for my own purposes so the code I have ready-to-hand is not VBA.
But It could be.

I've been too buried to build a working sample, but the guts are simple enough.
This code may work straight-up with a reference to WIA
A working sample is attached now, too

Option Compare Database
Option Explicit

Private Function CreateBuildPath() As String
CreateBuildPath = "c:\temp\"

End Function

Private Function GetFromCameraDevice()
'ok I want to get a camera and select some images from it

Dim i As Integer
Dim dev As WIA.Device
Dim itms As WIA.Items
Dim itm As WIA.Item
Dim Img As WIA.ImageFile
Dim s As String
Dim BuiltPath As String
Dim x As Integer
Dim Wait As Double
Dim success As Boolean
Dim ConfirmString As String


Dim DM As DeviceManager
Set DM = CreateObject("WIA.DeviceManager")

Dim CD As CommonDialog
Set CD = CreateObject("WIA.CommonDialog")
            
Dim fs As Object
Set fs = CreateObject("Scripting.FileSystemObject")

For i = 1 To DM.DeviceInfos.Count 'run through the devices in a loop
    Set dev = DM.DeviceInfos(i).Connect ' connect to it
    If dev.Type = CameraDeviceType And dev.Properties("Name").Value Like "canon*" Then ' if its a canon camera
        'MsgBox DM.DeviceInfos(i).Properties("Name").Value
       
        Set itms = CD.ShowSelectItems(dev, ColorIntent, MaximizeQuality, False, True, False)
        BuiltPath = CreateBuildPath()
        For Each itm In itms
            Set Img = itm.Transfer 'transfers the picture from the camera to an object that can be processed or saved
            s = BuiltPath & itm.Properties("Item Name").Value & ".jpg"
            Img.SaveFile (s) ' saves the raw image to a fully qualified filename
            
            'image saved, wait for completion
    
            x = 1
            Do Until success = True
                success = fs.FileExists(s) Or x = 3
                If success = False Then
                    Wait = Timer
                    While Timer < Wait + 1
                       DoEvents  'do nothing
                    Wend
                    success = fs.FileExists(s)
                    x = x + 1
                End If
            Loop
            If success = True Then
                If Nz(ConfirmString, "") = "" Then
                    ConfirmString = itm.Properties("Item Name").Value & ".jpg"
                Else
                    ConfirmString = ConfirmString & vbCrLf & itm.Properties("Item Name").Value & ".jpg"
                End If
                'MsgBox PicFileName & " transferred successfully!"
            Else
                MsgBox "The transfer of " & itm.Properties("Item Name").Value & ".jpg" & " failed"
            End If
            
    
        Next
    Else
        MsgBox "it's not a canon"
        Exit Function
    End If
    
    MsgBox ConfirmString & vbCrLf & "transferred successfully!"
Next
End Function

Private Sub Command0_Click()
Call GetFromCameraDevice
End Sub

Open in new window

pics.mdb

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jparisoAuthor Commented:
@Nick67

In that case I'll give it a go to see if I can get it to fit my application...
Nick67Commented:
@Chuck Lowe
Wrong reference for my stuff.
For that, you need a reference to WIA
Microsoft Windows Image Acquisition Library v2.0

Not WMI

Nick67
jparisoAuthor Commented:
Anybody trying to fiddle with Nick's code in access vba will have to enable the Reference Library "Microsoft Windows Image Acquisition Library v2.0"
jparisoAuthor Commented:
@Nick  Ha beat me too it by couple of minutes....

Your code appear to be working like a charm, modding it now!
jparisoAuthor Commented:
@Nick

Set itms = CD.ShowSelectItems(dev, ColorIntent, MaximizeQuality, False, True, False)

Open in new window

Can you explain to me what exactly this line is doing?
It obviously opens up some kind of fancy importation window, is that an inherant form in WIA?
Nick67Commented:
It obviously opens up some kind of fancy importation window, is that an inherent form in WIA?
Right.

The line creates a collection
Set itms
of WIA.Items from the selections the user makes in the WIA dialog box created here
Set CD = CreateObject("WIA.CommonDialog")
and displayed by the CD.ShowSelectItems

The dialog has no handles, no defaults, no settings you can muck with and cannot be manipulated by the VBA as it is paused waiting for the .ShowSelectItems to complete.

Unlike other Office-based dialog boxes, the WIA one doesn't remember size or location settings -- and always selects a default.
jparisoAuthor Commented:
I see your handprint on this thread...

http://www.experts-exchange.com/Database/MS_Access/Q_24749354.html

From puppydogbuddy:

Nick,
<<<Just as the FD.Show creates the FileDialog window, independent of any form, the CD.ShowSelectItems creates the WIA.CommonDialog box>>>>>
My problem is going to be I really don't want to use the wia.commonDialog box.  I have my own already programmed that is more robust and case specific than that one...
jparisoAuthor Commented:
So we are kind of back where we started (although a little further along), Nick you now have given me the code to find the camera devices very easily.

Below is my version of the code for VBA with the one line that needs to be replaced marked as such:

Public Function GetFromCameraDevice()

    On Error GoTo Log_Err
    Const SUBNAME As String = "GetFromCameraDevice"
    Call ErrorRoutineLog(MODULENAME, SUBNAME)

    'ok I want to get a camera and select some images from it
    
    Dim i As Integer
    Dim dev As WIA.Device
    Dim itms As WIA.Items
    Dim itm As WIA.Item
    Dim Img As WIA.ImageFile
    Dim s As String
    Dim BuiltPath As String
    Dim x As Integer
    Dim Wait As Double
    Dim success As Boolean
    Dim ConfirmString As String
    
    
    Dim DM As DeviceManager
    Set DM = CreateObject("WIA.DeviceManager")
    
    Dim CD As CommonDialog
    Set CD = CreateObject("WIA.CommonDialog")
                
    Dim fs As Object
    Set fs = CreateObject("Scripting.FileSystemObject")

    For i = 1 To DM.DeviceInfos.Count 'run through the devices in a loop
        Set dev = DM.DeviceInfos(i).Connect ' connect to it
        If dev.Type = CameraDeviceType Then
            'MsgBox DM.DeviceInfos(i).Properties("Name").Value
           
            "######## THIS LINE WILL NOT WORK FOR ME     Set itms = CD.ShowSelectItems(dev, ColorIntent, MaximizeQuality, False, True, False)
            
            For Each itm In itms
                Set Img = itm.Transfer 'transfers the picture from the camera to an object that can be processed or saved
                s = BuiltPath & itm.Properties("Item Name").Value & ".jpg"
                Img.SaveFile (s) ' saves the raw image to a fully qualified filename
                
                'image saved, wait for completion
        
                x = 1
                Do Until success = True
                    success = fs.FileExists(s) Or x = 3
                    If success = False Then
                        Wait = Timer
                        While Timer < Wait + 1
                           DoEvents  'do nothing
                        Wend
                        success = fs.FileExists(s)
                        x = x + 1
                    End If
                Loop
                If success = True Then
                    If Nz(ConfirmString, "") = "" Then
                        ConfirmString = itm.Properties("Item Name").Value & ".jpg"
                    Else
                        ConfirmString = ConfirmString & vbCrLf & itm.Properties("Item Name").Value & ".jpg"
                    End If
                    'MsgBox PicFileName & " transferred successfully!"
                Else
                    MsgBox "The transfer of " & itm.Properties("Item Name").Value & ".jpg" & " failed"
                End If
                
            Next

        End If
        
        MsgBox ConfirmString & vbCrLf & "transferred successfully!"
        
    Next
    
    Exit Function
    
Log_Err:

    Call ErrorHandler(lngErrorNum:=Err.Number, strErrorDescription:=Err.Description, strModuleName:=MODULENAME, strRoutineName:=SUBNAME, lngErrorLine:=Erl)
    gintForms(1) = Replace(gintForms(1), "[" & MODULENAME & " - " & SUBNAME & "]" & ", ", "", vbTextCompare)

End Function

Open in new window

The big question will be how to populate the WIA.Items (itms variable in your example) without using the WIA.CommonDialog box.
Nick67Commented:
That's the evil my friend.
I used FileSystemObject and the FileDialog object when a drive letter was assigned.

No drive letter, no joy for that approach.
That left WIA and its dialog box with its shortcomings.
That's why my original posting was in VBScript.

I Shelled out VBScript to set off CD.ShowSelectItems
I could then use VBA/WInAPI to manipulate the dialog box a little.
Sizing it was fairly easy.
Getting rid of the damned default item was not easy at all.
I had to simulate a mouse-click in whitespace -- and that can be quite flakey.
Nick67Commented:
Now -- depending on the situation -- you could just use WIA to suck ALL the images of the device and to a folder location.

Given that my guys don't delete images from the card, that's NOT a route I want to go -- but if you've looked at the articles, you are aware that you can dynamically resize.

You could conceivably create a folder of 'thumbnails' for users to select from
jparisoAuthor Commented:
@ Nick
Darn Darn Darny Darn! LOL

@Boyd
You're  on deck again, your device manger mod is looking better and better all the time!
Nick67Commented:
Say an 80 x 60 thumbnail?
What dialog box are you using now?
FileDialog?
jparisoAuthor Commented:
Home grown variety...
Capture2.JPG
Nick67Commented:
How big is the image?
jparisoAuthor Commented:
@Nick

Now -- depending on the situation -- you could just use WIA to suck ALL the images of the device and to a folder location.

If you can get me code  to mass import all images to any directory of my choosing automatically without using the wia.dialog box... I have a path to success!

How do I get WIA to suck every available picture to an arbitrary folder????
jparisoAuthor Commented:
Images are not big. I purposely buy cameras (which are harder and harder to find) that still allow the user to lop down the resolution.  I lop all pictures taken down to VGA (480 x 640 ???)  Very small in comparison to what the camera can actually take...
Nick67Commented:
I'm looking, but replace
Set itms = CD.ShowSelectItems(dev, ColorIntent, MaximizeQuality, False, True, False)
with
Set itms = dev.Items

and you may be in business
jparisoAuthor Commented:
...Preferably delete them as well well as transfer them...
jparisoAuthor Commented:
My friend... WELL PLAYED.  Works like a charm!  Any way to delete that item as it's transfered or after???
Nick67Commented:
It looks like

itms.Remove(itm.ItemID)

might do deletion
jparisoAuthor Commented:
I'm going to play with this tonight and see if I can't bring this to a conclusion.... give me a couple of hours.
Nick67Commented:
The resizing thing is a thing of joy.
No damn fool screwing with the camera settings is going to punch up 5-10-20 MB images with that in place.
First researched that when engineers insisted on taking images 4800 px wide for use in 2" image boxes on reports :(

Then came the need to print hundreds of images on a single report :)
jparisoAuthor Commented:
Thanks for the extra code on the resizing issue. I used to do my resizing when the image was rotated 90 degrees on import.  I've been lucky with my people not fooling around with the resolution on the camera for the last decade so the downsizing doesn't really get triggered and the image transfers remain fast.  The resizing in my case was just in case they decided to fool with the camera.

But, we are on the same page, no sense using large resolutions when the pictures on the shop paperwork are small, just slows everything up.

However your right if they change the resolution, I should resize it back down before transfer.  Does your resizing routine add a noticeable wait time for larger files???
jparisoAuthor Commented:
@Nick

itms.Remove(itm.ItemID)  is not working because item.ItemID is a string and item.Remove() expects a long integer...

https://msdn.microsoft.com/en-us/library/windows/desktop/ms630549%28v=vs.85%29.aspx

When I check on the .itemID string for the first picture I am testing, it displays as "o4", which is not an integer by default. Any ideas?
jparisoAuthor Commented:
It appear it is this instead...

You loop through the count using

For i = 1 To itms.Count 
     itms.Remove (itms.Count)

Open in new window


see this link

http://www.ammara.com/support/samples/code/viewcode_31b2.html

But that is less than satisfactory as I was:
1) hoping to check your Boolean Success variable before deleting
2) delete them as the get transferred instead of all at once at the end.

EDITED RESPONSE:

It appears I misunderstood the coding in that example. You loop through the count each time, checking the the item id of the loop count matches the item ID of the current file, when they match you use that count number to delete.  Very convoluted for sure!  Will try that approach now and see how it goes.
Nick67Commented:
We built it as a For Next
For Each itm In itms

Build it like so
Dim NumItems as Integer
Dim z as Integer

NumItems = itms.Count
For z = 1 to NumItems
...
'all the stuff that needs doing
'if it can be deleted
itms.Remove z


That's one way, and pehaps simplest, and most efficient.
You Ammara reference suggests another way:

They have a function
Private Function DeleteItem(ByRef WIA_Items As Object, ItemId As String) As Boolean
    'Note: Some Cameras don't support deleting pictures
    On Error GoTo Err_Handler
    Dim i As Integer
    DeleteItem = False

    For i = 1 To WIA_Items.Count ' Find the item with matching ItemId
        If WIA_Items(i).ItemId = ItemId Then ' Found item
            DeleteItem = True
            WIA_Items.Remove i
            Exit Function
        Else ' Not found, recurse (may be a directory)
            If (DeleteItem(WIA_Items(i).items, ItemId) = True) Then
                DeleteItem = True
                Exit Function
            End If
        End If
    Next
    
Exit_Here:
    Exit Function

Err_Handler:
    MsgBox Err.Description, vbOKOnly + vbCritical, "Error Deleting Picture From Camera"
    Resume Exit_Here

End Function

Open in new window


So use it!
DeleteItem(itms, itm.ItemID)
Will likely do the trick.

It's a bit wasteful compared to rewriting our stuff as For z = 1 to NumItems, since the function is doing exactly that
   For i = 1 To WIA_Items.Count ' Find the item with matching ItemId
        If WIA_Items(i).ItemId = ItemId Then ' Found item

And doing it each time its called.
jparisoAuthor Commented:
Ladies and Gentlemen we have a winner!

To recap, the code checks for all WIA devices that are listed as cameras.  It then loops through each object (i.e. image) on that device, transfers it to a designated destination on the c: drive (c:\DCIM\[Camera Name] to be exact) and then deletes the object image if the transfer of that file was successful.

This doesn't exactly follow the original intent of the original question as the images are off loaded first, but I thought about this last night and the offloading of the images of the camera is actually beneficial to our current operations and is better then leaving them on the camera...  BUT regardless, that distinction becomes academic because from the code listed below one could easily modify it.  Instead of transferring the object image immediately one could:  1) loop through and get the file name and image ID of the images  2) use the name and ID's in an access list box  3) code the list box or a button to transfer the selected item in the list box.

Thanks to Nick, Boyd and Chuck for all your effort!

The code I used is as follows:
(you must enable the Reference Library "Microsoft Windows Image Acquisition Library v2.0" )
(I left out the variable and object declartions, if you need those see some of the earlier posts...

    'CHECK FOR CAMERA FINAL DESITINATION FOLDER. If not there create it.
    strTemp = "C:\DCIM"
    If Dir(strTemp, vbDirectory) = "" Then MkDir (strTemp)

    intCount = 0

    'run through the devices in a loop
    For j = 1 To DM.DeviceInfos.Count

        ' connect to it
        Set dev = DM.DeviceInfos(j).Connect
        If dev.Type = CameraDeviceType Then

            strTemp = "C:\DCIM" & itm.Properties("Item Name").Value
            If Dir(strTemp, vbDirectory) = "" Then MkDir (strTemp)

            Set itms = dev.Items
            
            For Each itm In itms
            
                'transfers the picture from the camera to an object that can be processed or saved
                Set Img = itm.Transfer
                sFile = strTemp & "\" & itm.Properties("Item Name").Value & ".jpg"
                'check if file exists already, if so rename current file
                If Dir(strFileName, vbNormal) <> "" Then sFile = strTemp & "\" & itm.Properties("Item Name").Value & " - " & Int(Rnd() * 10000000) & ".jpg"
                'saves the raw image to a fully qualified filename
                Img.SaveFile (sFile)

                'image saved, wait for completion
                x = 1
                Do Until boolSuccess = True
                    boolSuccess = fs.FileExists(sFile) Or x = 3
                    If boolSuccess = False Then
                        Wait = Timer
                        While Timer < Wait + 1
                        DoEvents
                        Wend
                        boolSuccess = fs.FileExists(sFile)
                        x = x + 1
                    End If
                Loop
                If boolSuccess = True Then
                    'set Item ID to variable
                    strItemID = itm.ItemID
                    ' Find the item with matching ItemId
                    For k = 1 To itms.Count
                        ' Found item
                        If itms(k).ItemID = strItemID Then
                            DeleteItem = True
                            itms.Remove (k)
                            Exit For
                        Else
                            ' Not found, recurse (may be a directory)
                            If (DeleteItem(itms(i).Items, strItemID) = True) Then
                                DeleteItem = True
                                Exit For
                            End If
                        End If
                    Next
                    intCount = intCount + 1
                End If

            Next

        End If
    Next

Open in new window

jparisoAuthor Commented:
I would still like to see someone post the process needed to remove/change the wia nature of the camera device in the device manager, in case others that visit this thread choose to go that route.
Nick67Commented:
Thank you for posting this question.
I've worked long and hard to overcome the limitations of the WIA CommonDialog box.

It only struck me now that I shouldn't have bothered.

I could have used the techniques discussed here to:
Create a temp folder
Use WIA to fill it with 256 x 256 'thumbnail' images
Use the much more configurable FileDialog to select the images from the thumbnails

'Declare a variable as a FileDialog object.
Dim fd As FileDialog

'Create a FileDialog object as a File Picker dialog box.
Set fd = Application.FileDialog(msoFileDialogFilePicker)
'Declare a variable to contain the path
'of each selected item. Even though the path is a String,
'the variable must be a Variant because For Each...Next
'routines only work with Variants and Objects.
Dim vrtSelectedItem As Variant

'Use a With...End With block to reference the FileDialog object.
With fd
    .InitialView = msoFileDialogViewThumbnail
    .Title = "Picture Selector"
    '.InitialFileName = MyInitialFileName '"E:\DCIM"
    .InitialFileName = FDInitialFilename()
    .ButtonName = "Xfer and Save"

    'Use the Show method to display the File Picker dialog box and return the user's action.
    
    'The user pressed the action button.
    If .Show = True Then
'... more code

Open in new window


Then use WIA to retrieve the full-sized images from the camera for the user-selected results.
Kill the temp folder

That would have been simpler, more elegant and more bulletproof than my present approach of using VBScript to fire up the WIA.CommonDialog and using WinAPI via VBA to manipulate it.

Thanks for the inspiration.

Nick67
jparisoAuthor Commented:
EDITED CODE:  There were a couple of minor fixes

    'CHECK FOR CAMERA FINAL DESITINATION FOLDER. If not there create it.
    strTemp = "C:\DCIM"
    If Dir(strTemp, vbDirectory) = "" Then MkDir (strTemp)

    intCount = 0

    'run through the devices in a loop
    For j = 1 To DM.DeviceInfos.Count

        ' connect to it
        Set dev = DM.DeviceInfos(j).Connect
        If dev.Type = CameraDeviceType Then

            strTemp = "C:\DCIM\" & dev.Properties("Description").Value
            If Dir(strTemp, vbDirectory) = "" Then MkDir (strTemp)

            Set itms = dev.Items
            
            For Each itm In itms
            
                'transfers the picture from the camera to an object that can be processed or saved
                Set Img = itm.Transfer
                sFile = strTemp & "\" & itm.Properties("Item Name").Value & ".jpg"
                'check if file exists already, if so rename current file
                If Dir(strFileName, vbNormal) <> "" Then sFile = strTemp & "\" & itm.Properties("Item Name").Value & " - " & Int(Rnd() * 10000000) & ".jpg"
                'saves the raw image to a fully qualified filename
                Img.SaveFile (sFile)

                'image saved, wait for completion
                x = 1
                Do Until boolSuccess = True
                    boolSuccess = fs.FileExists(sFile) Or x = 3
                    If boolSuccess = False Then
                        Wait = Timer
                        While Timer < Wait + 1
                        DoEvents
                        Wend
                        boolSuccess = fs.FileExists(sFile)
                        x = x + 1
                    End If
                Loop
                If boolSuccess = True Then
                    'set Item ID to variable
                    strItemID = itm.ItemID
                    ' Find the item with matching ItemId
                    For k = 1 To itms.Count
                        ' Found item
                        If Nz(itms(k).ItemID, "") = strItemID Then
                            itms.Remove (k)
                            Exit For
                        End If
                    Next
                    intCount = intCount + 1
                End If
            Next
        End If

Open in new window

jparisoAuthor Commented:
@Nick

Glad you learned something from my problem... it's sounds like there are a number of people out there with this issue!

Thanks again.
jparisoAuthor Commented:
Small glitch related to cameras that are not WIA.  The code above will still recognize some cameras as WIA even if they are indeed setup with a drive path.  In my case, one loaction is using a wia camera and one loaction is using a camera that allows drive letter assignment. However they both appear as dev.Type = CameraDeviceType.

In my case I would like to skip the above coded routine for tradition cameras.  I could not find a dev.property that seemed to designate this but I did notice both the dev.properties("Description") and ("Name") Properties contain the drive letter (i.e "g:\") as their value while the wia camera has the cameral model as the value (i.e. "S3100")

Therefore, unless someone can find a better way, change the one line of code to this if you wish to do the same:

If dev.Type = CameraDeviceType And InStr(dev.Properties("Description").Value, ":\") = 0 Then

Open in new window

Nick67Commented:
In mine, I have a routine go through looking for folders off all drive letter roots named DCIM.
Only if no such folder is found does the WIA code kick into gear.
jparisoAuthor Commented:
Similar way to skin the cat, not exactly pretty either way however but as long as they work...
Nick67Commented:
Since I need the FileSystemObject for a plethora of other things if it finds a DCIM folder, and I don't necessarily need the WIA code unless no mass storage device camera is present, it works pretty well.  But other circumstances dictate other setups.

It's good to know that mass storage device cameras will present a drive letter as a device name, though.  I hadn't ever done any checking for a device name other that "*Canon*"
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Access

From novice to tech pro — start learning today.