Using VBA for attachments - vba

I'm trying to use VBA to attach a file to an existing table but I keep running into a Runtime 3709 error as documented on the line below. I have a table with a few thousand files in it. What I would like to do is give the user the ability to select the file to be attached and when it's saved, the name will show up on the form. Any help would be appreciated. Thanks.
Dim rsParent As DAO.Recordset
Dim rsAttachment As DAO.Recordset2
Dim strFileName As String
Dim SQL As String
Dim fDialog As Office.FileDialog
Dim varFile As Variant
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
.Title = "Choose the document to add to the form..."
.AllowMultiSelect = False
.InitialFileName = "C:\Users\"
If .Show = True Then
If .SelectedItems.Count = 0 Then
GoTo SubExit
End If ''
For Each varFile In .SelectedItems
strFileName = varFile
Next
Else
GoTo SubExit
End If
End With
SQL = "SELECT * FROM tblTable WHERE RecordID = " & Me.tbxRecordID
'Instantiate the parent recordset
Set rsParent = CurrentDb.OpenRecordset(SQL, dbOpenDynaset) ''
If rsParent.recordCount = 0 Then
MsgBox "There was a problem locating the selected record", vbCritical +
vbOKOnly, "Error"
GoTo SubExit
Else
' Put recordset in edit mode
rsParent.Edit
'Set the child recordset
Set rsAttachment = rsParent.Fields("Document").Value '**Runtime 3709 -
Search key not found**
'Add new attachment
rsAttachment.AddNew
rsAttachment.Fields("FileData").LoadFromFile strFileName
rsAttachment.Update
rsParent.Update
frmAttachments.Requery
End If
SubExit:
On Error Resume Next
If Not rsParent Is Nothing Then
rsParent.Close
Set rsParent = Nothing
End If
Exit Sub '
SubError:
MsgBox "Error Number: " & Err.Number & " = " & Err.Description, vbCritical + vbOKOnly, _
"An error occurred"
GoTo SubExit '
End Sub

Related

Replace a string in a .csv file before import into MS Access

I need to import multiple csv files into one access table, but before the import i would like to replace ",," with ",". Is there any way to do this?
For now i've got this code that only imports the files:
Private Sub bImportFiles_Click()
On Error GoTo bImportFiles_Click_Err
Dim objFS As Object, objFolder As Object
Dim objFiles As Object, objF1 As Object
Dim strFolderPath As String
Dim ts, tse As Date
ts = Now() 'Initializare start import
'Import fisiere colectare
strFolderPath = "C:\Users\costicla\test\"
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFS.GetFolder(strFolderPath)
Set objFiles = objFolder.files
For Each objF1 In objFiles
If Right(objF1.Name, 3) = "csv" Then
DoCmd.SetWarnings False
DoCmd.TransferText acImportDelim, "specs", "ALL", strFolderPath & objF1.Name, False
'DoCmd.RunSQL "INSERT INTO COLL_ALL ( Data_Inc, CNP, CB, CN, COM, N_UNITS, PUAN, Price, SN_ACT )"
Name strFolderPath & objF1.Name As "C:\Users\costicla\import\" & objF1.Name 'Move the files to the archive folder
End If
Next
Set objF1 = Nothing
Set objFiles = Nothing
Set objFolder = Nothing
Set objFS = Nothing
'tse = Now()
DoCmd.SetWarnings True
'MsgBox ("Import done !!! start at:" & ts & " end at:" & tse)
MsgBox ("Import ALL done !!! " & _
"start at: " & ts & " end at: " & tse)
bImportFiles_Click_Exit:
Exit Sub
DoCmd.SetWarnings True
bImportFiles_Click_Err:
MsgBox Err.Number & " " & Err.Description
Resume bImportFiles_Click_Exit
End Sub
You can use VBA's File I/O operations to open a file, import all of the data in one go, replace the double commas and output it to a new file. The code below should get you started:
Sub sReplaceDoubleComma(strInFile As String)
On Error GoTo E_Handle
Dim intInFile As Integer
Dim strOutFile As String
Dim intOutFile As Integer
Dim strInput As String
intInFile = FreeFile
Open strInFile For Input As intInFile
strOutFile = "J:\test-data\temp.txt"
intOutFile = FreeFile
Open strOutFile For Output As intOutFile
strInput = Input(LOF(intInFile), intInFile)
Print #intOutFile, Replace(strInput, ",,", ",")
Close #intInFile
Close #intOutFile
' Kill strInFile
' Name strOutFile As strInFile
sExit:
On Error Resume Next
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "sReplaceDoubleComma", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
End Sub
Once you are happy that this works, you can uncomment the two lines towards the end to replace the input file.
You can then call this procedure from within part of your existing code:
For Each objF1 In objFiles
If Right(objF1.Name, 3) = "csv" Then
DoCmd.SetWarnings False
Call sReplaceDoubleComma(strFolderPath & objF1.Name)
DoCmd.TransferText acImportDelim, "specs", "ALL", strFolderPath & objF1.Name, False
Name strFolderPath & objF1.Name As "C:\Users\costicla\import\" & objF1.Name 'Move the files to the archive folder
End If
Next
Link, don't import, the file, and you have a linked table.
Now, use this linked table as source in a simpel select query where you filter, modify, and convert the data and alias the fields as needed.
Then use this query as source in an append query that will add the records to your COLL_ALL table.

Error while copying Word tables to Excel using VBA

I am trying to copy a table from Microsoft Word 2016 to Microsoft Excel 2016 but not been very successful.
I get an error
User-defined type not defined
in this section of code below :
Public Sub ImportTableDataWordDoc(ByVal strDocName As String)
Could anyone help me with this, please?
The entire code follows:
Option Explicit
Public Sub ImportTableDataWord()
Const FOLDER_PATH As String = " \User\kritikata\Desktop\Articulateexporteddata\"
Dim sFile As String
sFile = Dir(FOLDER_PATH & " *.docx ")
If sFile = " " Then
MsgBox " The file is not present or was not found "
Exit Sub
End If
ImportTableDataWordDoc FOLDER_PATH & sFile
End Sub
Public Sub ImportTableDataWordDoc(ByVal strDocName As String)
Dim WdApp As Word.Application
Dim wddoc As Word.Document
Dim nCount As Integer
Dim rowWd As Long
Dim colWd As Long
Dim x As Long
Dim y As Long
Dim i As Long
On Error GoTo EH
If strDocName = "" Then
MsgBox "The file is not present or was not found"
GoTo FINISH
End If
Set WdApp = New Word.Application
WdApp.Visible = False
Set wddoc = WdApp.Documents.Open(strDocName)
If wddoc Is Nothing Then
MsgBox "No document object"
GoTo FINISH
End If
x = 1
y = 1
With wddoc
If .Tables.Count = 0 Then
MsgBox "No Tables Found in the document"
GoTo FINISH
Else
With .Tables(1)
For rowWd = 1 To .Rows.Count
For colWd = 1 To .Columns.Count
Cells(x, y) = WorksheetFunction.Clean(.Cell(rowWd, colWd).Range.Text)
y = y + 1
Next 'colWd
y = 1
x = x + 1
Next 'rowWd
End With
End If
End With
GoTo FINISH
EH:
With Err
MsgBox "Number" & vbTab & .Number & vbCrLf _
& "Source" & vbTab & .Source & vbCrLf _
& .Description
End With
'for debugging purposes
Debug.Assert 0
GoTo FINISH
Resume
FINISH:
On Error Resume Next
'release resources
If Not wddoc Is Nothing Then
wddoc.Close savechanges:=False
Set wddoc = Nothing
End If
If Not WdApp Is Nothing Then
WdApp.Quit savechanges:=False
Set WdApp = Nothing
End If
End Sub
The problem is that the sFile = Dir(FOLDER_PATH & " *.docx ") does not get the correct docx file.
This is visible, if you write MsgBox FOLDER_PATH & sFile before calling the sub.

Export specific information from Access 2016 to a Word document that is already created

I am trying to export data from a Access 2016 Form to a Word document. Here is the code I'm using.
Public Function doWordAutomation()
On Error GoTo doWordAutomationErr
Dim objWordDoc As Word.Document
Dim objWord As Word.Application
Dim sDocument As String
sDocument = Application.CurrentProject.Path & "C:Desktop\No Notary Legal Dispatch Affidavit Fill.doc"
Set objWord = CreateObject("Word.Application")
Set objWordDoc = objWord.Documents.Open(Application.CurrentProject.Path & "\C:\Desktop\No Notary Legal Dispatch Affidavit Fill.doc")
If (sDocument) Then
Kill sDocument
End If
objWordDoc.SaveAs sDocument
With objWordDoc.Bookmarks
If .Exists("Cause") Then
.Item("Cause").Range.Text = "Cause"
If .Exists("Plaintiff") Then
.Item("Plaintiff").Range.Text = "Plaintiff"
If .Exists("Court") Then
.Item("Court").Range.Text = "Court"
If .Exists("County") Then
.Item("County").Range.Text = "County"
If .Exists("State") Then
.Item("State").Range.Text = "State"
If .Exists("Defendant") Then
.Item("Defendant").Range.Text = "Defendant"
If .Exists("Documents") Then
.Item("Documents").Range.Text = "Documents"
If .Exists("NameforService") Then
.Item("NameforService").Range.Text = "NameforService"
If .Exists("ServiceAddress") Then
.Item("ServiceAddress").Range.Text = "ServiceAddress"
If .Exists("ResultTime") Then
.Item("ResultTime").Range.Text = "ResultTime"
If .Exists("ResultDate") Then
.Item("ResultDate").Range.Text = "ResultDate"
End If
End
objWordDoc.Save
objWordDoc.Close
doWordAutomationExit:
Exit Function
doWordAutomationErr:
MsgBox Err.Description, vbOKOnly, Err.Source & ":" & Err.Number
Resume doWordAutomationExit
End Function
I have created a button in my form and attached this code to it but when I try to use it nothing happens. Any help that you can give will be greatly appreciated.
Private Sub cmdPrint_Click()
'Print customer slip for current customer.
Dim appWord As Word.Application
Dim doc As Word.Document
'Avoid error 429, when Word isn’t open.
On Error Resume Next
Err.Clear
'Set appWord object variable to running instance of Word.
Set appWord = GetObject(, "Word.Application")
If Err.Number <> 0 Then
'If Word isn’t open, create a new instance of Word.
Set appWord = New Word.Application
End If
Set doc = appWord.Documents.Open("C:C:Desktop\No Notary Legal Dispatch Affidavit Fill.doc", , True)
With doc
.FormFields("Cause").Result = Me!Cause
.FormFields("Plaintiff").Result = Me!Plaintiff
.FormFields("Court").Result = Me!Court
.FormFields("County").Result = Me!County
.FormFields("State").Result = Me!State
.FormFields("Defendant").Result = Me!Defendant
.FormFields("Documents").Result = Me!Documents
.FormFields("NameforService").Result = Me!NameforService
.FormFields("ServiceAddress").Result = Me!ServiceAddress
.FormFields("ResultTime").Result = Me!ResultTime
.FormFields("ResultDate").Result = Me!ResultDate
.Visible = True
.Activate
End With
Set doc = Nothing
Set appWord = Nothing
Exit Sub
errHandler:
MsgBox Err.Number & ": " & Err.Description
End Sub
I have created bookmarks in a Word document that I'm wanting to export the form information into. Neither code I used worked for me so any help would be greatly appreciated.
For some reason, it is still not working. I don't know if it is the button that I have put in the form, which is a command76 button. I know that's not the exact right button I need to export but it's the closest one I see that I'm able to use. I have attached the access document and word document that I'm trying to use. The Word form with bookmarks Word Document and the Access Form Access Document have been linked here. Thanks again in advance for your help. Attached are two of the documents I'm trying to use.
Now that you have shared the document and names, I changed the code to use the data from your form. You may need to tweak the document spacing or the data you insert. Let me know how it goes.
Also, I suggest you clean up this thread by deleting the unnecessary descriptions and comments.
Option Compare Database
Option Explicit
Private Sub Command75_Click()
Export_Form_Data_To_Word
End Sub
Public Function Export_Form_Data_To_Word()
Dim objWordDoc As Word.Document
Dim objWord As Word.Application
Dim objRange As Word.Range
Dim sPath As String
Dim sFileName As String
Dim sSaveAs As String
Dim sDocument As String
Dim i As Integer
On Error GoTo Error_Trap
' For my testing....
'sPath = "C:\temp\" '
'sFileName = "NoNotaryLegalDispatchAffidavitFill.docx" '
sPath = "C:\Users\Josh Panger\Desktop" '
sFileName = "No Notary Legal Dispatch Affidavit Fill.docx" '
i = InStrRev(sFileName, ".doc") '
' Create a new file name
sSaveAs = Left(sFileName, i - 1) & "_" & Format(Now(), "YYYYMMDD_HHMMSS") & Mid(sFileName, i)
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
Set objWordDoc = objWord.Documents.Open(sPath & sFileName)
With objWordDoc.Bookmarks
If .Exists("Cause") Then
objWordDoc.Bookmarks("Cause").Range.InsertAfter Me.Cause
Else
MsgBox "Bookmark: 'Cause' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("Plaintiff") Then
objWordDoc.Bookmarks("Plaintiff").Range.InsertAfter Me.Plaintiff & ", Plaintiff"
Else
MsgBox "Bookmark: 'Plaintiff' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("Defendant") Then
objWordDoc.Bookmarks("Defendant").Range.InsertAfter Me.Defendant & ", Defendant"
Else
MsgBox "Bookmark: 'Defendant' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("Court") Then
objWordDoc.Bookmarks("Court").Range.InsertAfter Me.Count
Else
MsgBox "Bookmark: 'Court' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("County") Then
objWordDoc.Bookmarks("County").Range.InsertAfter Me.County
Else
MsgBox "Bookmark: 'County' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("State") Then
objWordDoc.Bookmarks("State").Range.InsertAfter "My State"
Else
MsgBox "Bookmark: 'State' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("Documents") Then
objWordDoc.Bookmarks("Documents").Range.InsertAfter Me.Documents
Else
MsgBox "Bookmark: 'Documents' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("NameforService") Then
objWordDoc.Bookmarks("NameforService").Range.InsertAfter Me.NameforService
Else
MsgBox "Bookmark: 'NameforService' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("ServiceAddress") Then
objWordDoc.Bookmarks("ServiceAddress").Range.InsertAfter Me.ServiceAddress
Else
MsgBox "Bookmark: 'ServiceAddress' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("ResultTime") Then
objWordDoc.Bookmarks("ResultTime").Range.InsertAfter Me.ResultTime
Else
MsgBox "Bookmark: 'ResultTime' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("ResultDate") Then
objWordDoc.Bookmarks("ResultDate").Range.InsertAfter Me.ResultDate
Else
MsgBox "Bookmark: 'ResultDate' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
End With
objWordDoc.SaveAs2 sPath & sSaveAs, 16
objWordDoc.Close
Exit_Code:
Exit Function
Error_Trap:
Debug.Print Err.Number & vbTab & Err.Description
If Err.Number = 5174 Then
MsgBox "The Word document can't be found at location: '" & sDocument & "'", vbOKOnly, "Missing File"
Else
MsgBox Err.Number & vbTab & Err.Description, vbOKOnly, Err.Source & ":" & Err.Number
End If
Resume Exit_Code
Resume
End Function

Select filename using FileDialog

I am trying to get a fullpath and filename using the file dialog from MS Access VBA.
What I am trying to do is to open the file Dialog on button click by calling this function. This function should return the fullpath and filename that was selected from the filedialog.
I commented the loop part because I only want to select single file.
This function is returning an error Error: 0 after I select a file
So far this is my code.
Anyone can figure out what's wrong?
Thanks
Public Function SelectTheFile() As String
On Error GoTo SelectTheFile_ErrorHandler
Dim fDialog As Office.FileDialog
Dim varFile As Variant
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
.AllowMultiSelect = False
.Title = "Please select one file"
If .Show = True Then
'For Each varFile In .SelectedItems
'SelectTheFile = varFile
'Debug.Print SelectTheFile
'Next
SelectTheFile = .SelectedItems(1)
Debug.Print SelectTheFile
Else
Debug.Print "Cancel"
End If
End With
SelectTheFile_ErrorHandler:
Set fd = Nothing
MsgBox "Error " & Err & ": " & Error(Err)
End Function
your code always reach the SelectTheFile_ErrorHandler: section whatever the file dialog result
you must exit the function before that section
Public Function SelectTheFile() As String
On Error GoTo SelectTheFile_ErrorHandler
Dim fDialog As Office.FileDialog
Dim varFile As Variant
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
.AllowMultiSelect = False
.Title = "Please select one file"
If .Show = True Then
'For Each varFile In .SelectedItems
'SelectTheFile = varFile
'Debug.Print SelectTheFile
'Next
SelectTheFile = .SelectedItems(1)
Debug.Print SelectTheFile
Else
Debug.Print "Cancel"
End If
End With
Exit Function '<==== exit here, otherwise code goes on to following section
SelectTheFile_ErrorHandler:
Set fDialog = Nothing
MsgBox "Error " & Err & ": " & Error(Err)
End Function
Try just using this:
Application.GetOpenFilename
That works for me and saves the full file path without actually opening the file. Much simpler unless I am missing what you're trying to do. Read more here in the docs: https://msdn.microsoft.com/en-us/library/office/ff834966.aspx

For Each loop: How to adjust code to move files in one run rather than multiple

I am using the below code to archive emails that have been marked completed. It is supposed to check all emails in our shared folder for anything marked complete prior to today's date. It works, but I must run the code multiple times to archive all of the affected quoted. Does anyone have any ideas how to get this to work in one shot?
Public Const CEpath As String = "\\s-estimating\CentralEstimating\"
Option Explicit
Public Const sArchivePath As String = Miscellaneous.CEpath + "Archives\"
Public Sub ArchiveInbox()
Dim dtDateToMove As Date
Dim iMessageCount As Integer
Dim oDestination As MAPIFolder
Dim oFileName As String
Dim oNamespace As NameSpace
Dim oMailItem As MailItem
Dim oProgress As New ProgressDialogue
Dim oSource As MAPIFolder
Dim oStore As Store
Dim oOSPsource As MAPIFolder
'Dim oOSPDestination As MAPIFolder
On Error GoTo HandleError
' Obtain a NameSpace object reference.
Set oNamespace = Application.GetNamespace("MAPI")
Set oStore = oNamespace.Stores.item("Rings")
Set oSource = oStore.GetDefaultFolder(olFolderInbox)
' try to connect to the OSP Folder
On Error Resume Next
'Debug.Print oSource.Folders("OSP Quotes").Items.count
Set oOSPsource = oSource.Folders("OSP Quotes")
On Error GoTo HandleError
' Start Progess form
oProgress.Configure title:="Archive Old RFQs", _
status:="Please stand by while the operation is being processed…", _
Min:=0, _
Max:=CDbl(oSource.Items.count), _
optShowTimeElapsed:=True, _
optShowTimeRemaining:=True
oProgress.Show vbModeless
' Open Archive (or create and open)
dtDateToMove = PreviousBusinessDay(Date)
If Month(PreviousBusinessDay(Date)) < 7 Then
oFileName = "RFQs " & Year(dtDateToMove) & " - Jan-Jun"
Else
oFileName = "RFQs " & Year(dtDateToMove) & " - Jul-Dec"
End If
' Debug.Print dtDateToMove
' Debug.Print oFileName
oNamespace.AddStoreEx Store:=sArchivePath & oFileName & ".pst", _
Type:=olStoreUnicode
Set oDestination = oNamespace.Folders.GetLast
If Not oDestination.Name = oFileName Then oDestination.Name = oFileName
' Sort through all closed emails in Rings and move them to the archive folder
For Each oMailItem In oSource.Items
iMessageCount = iMessageCount + 1
If oProgress.cancelIsPressed Then Exit For
' Debug.Print " " & oMailItem.TaskCompletedDate
If oMailItem.FlagStatus = olFlagComplete Then
If oMailItem.IsConflict Then
Err.Raise Number:=95, _
Description:="Mail Item Conflict Detected"
End If
If oMailItem.TaskCompletedDate <= dtDateToMove Then
oMailItem.Move oDestination
' Debug.Print " Moved"
End If
End If
oProgress.SetValue iMessageCount
Next oMailItem
ExitRoutine:
oProgress.Hide
If oOSPsource Is Nothing Then
Debug.Print "OSP Quotes folder was not found."
Else
If oOSPsource.Items.count > 0 Then
MsgBox "There are items in OSP Quotes.", vbInformation + vbOKOnly
End If
End If
' close the store
oNamespace.RemoveStore oDestination
Set oProgress = Nothing
Set oDestination = Nothing
' Set oOSPDestination = Nothing
Set oOSPsource = Nothing
Set oSource = Nothing
Set oStore = Nothing
Set oNamespace = Nothing
Exit Sub
HandleError:
Debug.Print Err.Number
Debug.Print Err.Description
Select Case Err.Number
Case 95
MsgBox Prompt:=oMailItem.Subject & vbCrLf & vbCrLf & "An email with the above subject line is in conflict." & _
vbCrLf & "You will need to resolve the conflict and run Export to Excel again.", _
Buttons:=vbCritical + vbOKOnly, _
title:="Conflict Resolution Required"
oProgress.Hide
GoTo ExitRoutine
Case Else
If Not ErrorHandling.ErrorLog(Err.Number, Err.Description, "Archive The Inbox") Then
Err.Clear
Resume
End If
End Select
End Sub
Do not use "for each" loop if you are modifying the collection
Change the loop
For Each oMailItem In oSource.Items
to a down "for" loop:
dim oItems = oSource.Items
for I = oItems.Count to 1 step -1
set oMailItem = oItems.Item(I)