-7

I have around 100 rows in MS Access, each row includes an attachment. Using RODBC in R I can access the table but have no idea how to access attached files and download them in R

could you plz help me how to do it

  • I think folks are being unfair to this question. I haven't used MS Access in a long time so cannot help you with this. You might ask around in MS access forums and explore other scripting languages. – Rohit Das Oct 14 '16 at 23:20
  • Just a comment: I tried something similar (dealing with images in a binary cell) and, though I don't recall where I looked, I spent a lot of time and found no way to access it through RODBC. Not to say it's not possible, but if your luck is anything like mine, you may need to find another mechanism. – r2evans Oct 15 '16 at 00:47
  • I have used RODBC to query binary data (images and other files, including pdf and excel). Here's another question you can study. http://stackoverflow.com/questions/39581256/r-help-data-from-odbc-blob-not-matching-return-from-sql-query/39593187#39593187 I have only done this in MS SQL Server, so can't comment on how this will work with Access. – Benjamin Oct 15 '16 at 01:49

1 Answers1

0

Attachments in MS Access are special data types that actually involve nested tables for metadata (filename and filedata) information. Hence, you cannot access this data with DML SQL statements alone via RODBC but can using a COM interface, specifically connecting to the DAO SaveToFile() method.

Consider the following using the RDCOMClient package which allows interfacing to the Access Object Library. Do note: in order to run the below code, you must have MSAccess.exe (the MS Office GUI program) installed and not just the .accdb file. In the SQL query below, ColAttach is the name of the attachment field in your table and you must use those qualifiers .filedata and .filename. DAO recordset field numbers are zero based (hence the 0 and 1).

library(RDCOMClient)

# INITIALIZING OBJECTS
accApp <- COMCreate("Access.Application")
accApp$OpenCurrentDatabase("C:\\Path\\To\\Database.accdb")
docmd <-  accApp[["DoCmd"]]
db <- accApp$CurrentDb()

rst <- db$OpenRecordset("SELECT ColAttach.filedata, ColAttach.filename FROM TblAttach")

while(rst$EOF() == FALSE){     
  rst$Fields(0)$SaveToFile(paste0("C:\\Path\\To\\Output_", rst$Fields(1)$Value()))      
  rst$MoveNext()
}

# CLOSING OBJECTS
rst$close()
docmd$CloseDatabase()
accApp$Quit()

# RELEASING RESOURCES
accApp <- db <- docmd <- rst <- NULL    
rm(rst, db, accApp)
gc()

For multiple attachments, loop through the child recordset on each filename and filedata values (notice the different SQL). Be sure to check if file exists and destroy accordingly else you will receive a COM error:

rst <- db$OpenRecordset("SELECT ID, ColAttach FROM TblAttach")

while(rst$EOF() == FALSE){    
  childRS <- rst[['ColAttach']]$Value()

  while(childRS$EOF() == FALSE){
    if (file.exists(paste0("C:\\Path\\To\\Output_", childRS[["filename"]]$Value()))) {
      unlink(paste0("C:\\Path\\To\\Output_", childRS[["filename"]]$Value()))
    }

    childRS[["filedata"]]$SaveToFile(paste0("C:\\Path\\To\\Output_", 
                                     childRS[["filename"]]$Value()))
    childRS$MoveNext()
  }

  rst$MoveNext()
}
Parfait
  • 104,375
  • 17
  • 94
  • 125
  • thank you so very much, it was just what I searched. however if field contains more than two attached files I am getting an error. – user7021605 Oct 19 '16 at 17:43
  • You will need to run another loop for child recordset. Same logic as the VBA shown in [posted link](https://msdn.microsoft.com/en-us/library/office/ff191852.aspx) See edited answer. Please accept if answer helped and to confirm resolution. – Parfait Oct 19 '16 at 19:35
  • you are the best ! thanks a lot :) – user7021605 Oct 20 '16 at 20:05
  • Great! Glad I could help. Please accept answer by click tick mark to side. This confirms resolution. – Parfait Oct 20 '16 at 20:17