View only most recently added attachment in Access report - ms-access

I'm using an access database as a member management application for our swimming pool. I use a report to print out all of the season passes that have a picture ID. The report uses a query to only print passes for patrons who have had their photo taken.
SELECT tblPassHolders.[PASS HOLDER NAME], tblPassHolders.PHOTO.FileData, tblPassHolders.BARCODE, tblPassHolders.[FAMILY PASS], tblFamilyPass.Expires
FROM tblFamilyPass INNER JOIN tblPassHolders ON tblFamilyPass.ID = tblPassHolders.FamilyID
WHERE (((tblPassHolders.PHOTO.FileData) Is Not Null) AND ((tblFamilyPass.Expires)>Now()) AND ((tblPassHolders.Printed)=False));
This is year two of using the application, and the problem I'm having is when people re-take their pictures for their pass, then my report prints out a pass for each photo attachment attached to their record.
I'm very amateur with Access still and I'm struggling to figure out how to edit my report/query so that the report will only print one pass for each patron using the most recent photo attached to their record. One solution is to simply delete the old photos so there's only ever one attachment, but I'd like to figure out how to make it work even if there are multiple attachments. I've been playing around with DLast() but I'm pretty sure I'm doing it wrong.
How do I make a query that will only show the most recently added attachment?

Here is an example of what I was suggesting you could do instead of finding the most recently added attachment.
As discussed it's impossible unless you implement some kind of naming convention that pops your latest file to the top, because Microsoft shows the attachment field in order of filename.
Here's an example that you can use a button to control inserting the attachments.
It's based on the Stack Overflow example
Once you finish testing you can add Cancel=True to the Photo_DblClick event to completely control your Photo Attachments field
Private Sub cmdAddNewPhoto_Click()
Dim rsPhotos As DAO.Recordset2
Dim rsParent As DAO.Recordset2
Dim strImagePath As String
If MsgBox("Add New Photo?", vbQuestion + vbOKCancel, "Add Photo?") = vbOK Then
' Get New Photo
' Note that you need to add a reference to Microsoft Office ##.0 Object Library
' using Tools | References... from the VBA interface for the file picker to work
With Application.FileDialog(msoFileDialogFilePicker)
' Prevent multiple selections
.AllowMultiSelect = False
' Set the caption of the dialog box
.Title = "Please select a photo"
' Add filters for common image formats
.Filters.Clear
.Filters.Add "JPG Files (JPG)", "*.JPG"
.Filters.Add "JPEG Files (JPEG)", "*.JPEG"
.Filters.Add "PNG Files", "*.PNG"
.Filters.Add "Bitmap Files", "*.BMP"
If .Show = True Then ' File selected
strImagePath = .SelectedItems.item(1)
End If
End With
If strImagePath <> "" Then
' First clear all old photos if desired
If Photo.AttachmentCount > 0 Then
If MsgBox("Clear Previous Photo(s)?", vbQuestion + vbOKCancel, "Remove All Photos?") = vbOK Then
' Clear previous attachments
' (we only want one attachment at a time)
Set rsPhotos = Me.Recordset.Fields("Photo").Value
With rsPhotos
Do While Not .EOF
.Delete
.MoveNext
Loop
.Close
End With
' Clear last displayed photo
Photo.Requery
End If
End If
' Put parent record in edit mode
Set rsParent = CurrentDb.OpenRecordset(Me.RecordSource, dbOpenDynaset)
With rsParent
' Get Cureent Matching Record using Primary Key
.FindFirst "BarCode = " & Me!barcode
.Edit
DoEvents
End With
' Next Add the attachment selected by the user
Set rsPhotos = rsParent.Fields("Photo").Value
With rsPhotos
.AddNew
.Fields("FileData").LoadFromFile strImagePath
If Photo.AttachmentCount > 0 Then
' Rename so it pops up to first file - and keep extension
.Fields("Filename").Value = "00000LatestPic" & Mid$(strImagePath, InStrRev(strImagePath, "."))
End If
.Update
.Close
End With
' Update the parent record
With rsParent
.Update
.Close
End With
Set rsPhotos = Nothing
Set rsParent = Nothing
' Refresh Photo Display
Photo.Requery
End If
End If
End Sub

Related

VBA to convert a query to a table [duplicate]

I have a CSV file that needs to be imported into Access using a linked table. However, this exceeds the 255 column limit.
This was solved by using some VBA with a button. On press the data is loaded into a linked table. I now need to add some extra code under this to create a copy of the linked table and save it as a local table.
This needs to be done on one press of the button. Below is what i have got currently.
Private Sub cmdImportExcel_Click()
'DoCmd.TransferSpreadsheet acImport, , "tblRawTestData", "C:\Users\jacklythgoe\documents\Access\Test Analyzer\data\TestResultsCopy.csv", True, Range:="TestResultsCopy!A:C"
' Requires reference to Microsoft Office 11.0 Object Library.
Dim fDialog As Office.FileDialog
Dim varFile As Variant
Dim testResultsWorkSheet As Worksheet, strFile As String
' Set up the File Dialog.
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
' Allow user to make multiple selections in dialog box
.AllowMultiSelect = True
' Set the title of the dialog box.
.Title = "Please select the font(s)."
' Clear out the current filters, and add our own.
.Filters.Clear
.Filters.Add "Text File", "*.csv"
' Show the dialog box. If the .Show method returns True, the
' user picked at least one file. If the .Show method returns
' False, the user clicked Cancel.
If .Show = True Then
'Loop through each file selected and add it to our list box.
For Each varFile In .SelectedItems
Next
End If
End With
DoCmd.TransferText TransferType:=acLinkDelim, tableName:="tblImport", FileName:="C:\Users\jacklythgoe\Documents\Access\Test Analyzer\data\TestResultsCopy.csv", HasFieldNames:=False
'DoCmd.TransferText TransferType:=acLinkDelim, TableName:="tblImport", FileName:="C:\MyData.csv", HasFieldNames:=True
End Sub
You could try something like this:
DoCmd.CopyObject , "tblImport_Copy", acTable, "tblImport"
DoCmd.SelectObject acTable, "tblImport_Copy", True
DoCmd.RunCommand acCmdConvertLinkedTableToLocal
Makes a copy of the linked table, 2. Selects the copy, 3. Converts into a lokal table
Not sure if you have all the details in your question.
If you already have solved the issue with the linking the CSV file as a table, then just build a make table query that selects the fields from the linked csv file and run the query from your button click event. It creates a local table for you
Something like this would work:
Dim dbs As DAO.Database
Dim lngRowsAffected As Long
Dim lngRowsDeleted As Long
Set db = CurrentDb
' Execute runs both saved queries and SQL strings
db.Execute <mymaketablequery>, dbFailOnError
' Get the number of rows inserted.
lngRowsAffected = db.RecordsAffected
Msgbox "Inserted " & lngRowsAffected & " new records"

Creating a button in Access to to open a word document

I have a word document that uses mail merge feature and gets its information from the access db. When I use this code it does not open the word document with the current information. It opens the word document with the last saved information.
If I open the word document on its own, from the task bar, it asks if I want to run the SQL and I click yes and everything operates normally. I want to click a button from within access to accomplish this same task to open the contract.
Here is the code I used:
Private Sub Command205_Click()
Dim LWordDoc As String
Dim oApp As Object
'Path to the word document
LWordDoc = "C:\Users\.....k Up\01- Proposal\contract.docx"
If Dir(LWordDoc) = "" Then
MsgBox "Document not found."
Else
'Create an instance of MS Word
Set oApp = CreateObject(Class:="Word.Application")
oApp.Visible = True
'Open the Document
oApp.Documents.Open FileName:=LWordDoc
End If
End Sub
***I should add that I am not a coder and know nothing about VBA, I copied this from this website so any help you can offer would be greatly appreciated. If you can provide me with coding or enough guidance to get me on the way would be great. Thank you
This code will run in Access to open a Mail Merge document and update content and save.
Using the link I originally posted (http://www.minnesotaithub.com/2015/11/automatic-mail-merge-with-vba-and-access/), I made a couple of modifications and was able to get that code to work.
I needed to add: ReadOnly:=True, _ to prevent a sharing violation
and I changed the Table Name of the source data.
NOTE!! You will need to change sode marked with'###' as follows:
###-1 Change to specify the full path of your TEMPLATE!!!
###-2 Change the SQLSTATEMENT to specify your recordsource!!!
Paste this code into your form, make sure you have a Command Button Click Event that executes (Either rename 'Command205' in this code, or change your control name).
Option Compare Database
Option Explicit
Private Sub Command205_Click()
Dim strWordDoc As String
'Path to the word document of the Mail Merge
'###-1 CHANGE THE FOLLOWING LINE TO POINT TO YOUR DOCUMENT!!
strWordDoc = "C:\Users\.....k Up\01- Proposal\contract.docx"
' Call the code to merge the latest info
startMerge strWordDoc
End Sub
'----------------------------------------------------
' Auto Mail Merge With VBA and Access (Early Binding)
'----------------------------------------------------
' NOTE: To use this code, you must reference
' The Microsoft Word 14.0 (or current version)
' Object Library by clicking menu Tools > References
' Check the box for:
' Microsoft Word 14.0 Object Library in Word 2010
' Microsoft Word 15.0 Object Library in Word 2013
' Click OK
'----------------------------------------------------
Function startMerge(strDocPath As String)
Dim oWord As Word.Application
Dim oWdoc As Word.Document
Dim wdInputName As String
Dim wdOutputName As String
Dim outFileName As String
' Set Template Path
wdInputName = strDocPath ' was CurrentProject.Path & "\mail_merge.docx"
' Create unique save filename with minutes and seconds to prevent overwrite
outFileName = "MailMergeFile_" & Format(Now(), "yyyymmddmms")
' Output File Path w/outFileName
wdOutputName = CurrentProject.Path & "\" & outFileName
Set oWord = New Word.Application
Set oWdoc = oWord.Documents.Open(wdInputName)
' Start mail merge
'###-2 CHANGE THE SQLSTATEMENT AS NEEDED
With oWdoc.MailMerge
.MainDocumentType = wdFormLetters
.OpenDataSource _
Name:=CurrentProject.FullName, _
ReadOnly:=True, _
AddToRecentFiles:=False, _
LinkToSource:=True, _
Connection:="QUERY mailmerge", _
SQLStatement:="SELECT * FROM [tblEmployee]" ' Change the table name or your query
.Destination = wdSendToNewDocument
.Execute Pause:=False
End With
' Hide Word During Merge
oWord.Visible = False
' Save file as PDF
' Uncomment the line below and comment out
' the line below "Save file as Word Document"
'------------------------------------------------
'oWord.ActiveDocument.SaveAs2 wdOutputName & ".pdf", 17
' Save file as Word Document
' ###-3 IF YOU DON'T WANT TO SAVE AS A NEW NAME, COMMENT OUT NEXT LINE
oWord.ActiveDocument.SaveAs2 wdOutputName & ".docx", 16
' SHOW THE DOCUMENT
oWord.Visible = True
' Close the template file
If oWord.Documents(1).FullName = strDocPath Then
oWord.Documents(1).Close savechanges:=False
ElseIf oWord.Documents(2).FullName = strDocPath Then
oWord.Documents(2).Close savechanges:=False
Else
MsgBox "Well, this should never happen! Only expected two documents to be open"
End If
' Quit Word to Save Memory
'oWord.Quit savechanges:=False
' Clean up memory
'------------------------------------------------
Set oWord = Nothing
Set oWdoc = Nothing
End Function

Get Form Recordsource without opening the form

Does MS Access allow to get the recordsource value of the form without opening the form itself? I'm trying to optimize my code as of now, what I did is I just hide the form then get the Recordsource form query but it takes time to load since some of the forms trigger a code upon onload.
I'm late to the game here - I sometimes post answers months or years after the original question was posted, as I post my own solutions when a quick search of the 'Stack finds questions relevant to my own problem of the day, but no answers that I can actually use.
[UPDATE, 06 June 2016]
The 'NameMap' property is not available in document objects from Access 2010 onwards. However, 'Stacker Thunderframe has pointed out that this is now available in the 'MsysNameMap' table.
I have amended the code, and this works in Access 2010 and 2013.
[/UPDATE]
Most of a form's properties are only available when the form is open, but some are available in the form's entry in the DAO Documents collection.
The DAO 'document' is a horrible object: it won't persist in memory and you have to refer to it explicitly every time you use it:
FormName = "MyForm"
For i = 0 To Application.CodeDb.Containers("Forms").Documents(FormName).Properties.Count - 1
Debug.Print i & vbTab & Application.CodeDb.Containers("Forms").Documents(FormName).Properties(i).Name & vbTab & vbTab & Application.CodeDb.Containers("Forms").Documents(FormName).Properties(i).Value
Next
Run that snippet for your form, and you'll see a 'NameMap' property that contains a list of the form's controls, and some of the form's properties.
...In a truly horrible format which needs a binary parser. You might want to stop reading and take an aspirin, right now, before continuing.
Health Warnings:
The NameMap Property is undocumented. It is therefore unsupported and there is no guarantee that this solution will work in future versions of Microsoft Access.
The solution in my code below will stop working if the NameMap's two-byte binary label for a Record Source ever changes, or if it's locale-specific.
This is a horrible hack: I accept no liability for any effects on your sanity.
OK, here's the code:
A VBA function to return the Record Source from a closed MS-Access form:
Private Function FormRecordSource_FromNameMap(FormName As String) As String
' Reads the Record Source from the NameMap Property of the Document object for the form.
' WARNING: there is a potential error here: if the form's RecordSource property is blank
' and it has one or more list controls with a .RecordSource property populating
' the list, this function will return the first list control's Record Source.
' This won't work if you're using non-ASCII characters (Char > 255) in your form name.
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim arrByte() As Byte
Dim strOut As String
If Application.Version &LT; 12 Then
arrByte = Application.CodeDb.Containers("Forms").Documents(FormName).Properties("NameMap").Value
For i = 1 To UBound(arrByte) - 2 Step 2
' 2-byte marker for a querydef in the NameMap:
If (arrByte(i) = 228 And arrByte(i + 1) = 64) Then
j = i + 2
Do While arrByte(j) = 0 And arrByte(j + 1) = 0 And j &LT; UBound(arrByte)
' loop through the null chars between the marker and the start of the string
j = j + 2
Loop
strOut = ""
Do Until (arrByte(j) = 0 And arrByte(j + 1) = 0) Or j &GT;= UBound(arrByte) - 2
If arrByte(j) = 0 Then j = j + 1
' loop until we reach the null char which terminates this string
' appending the Bchars (not unicode Wchars!) of the table or query
strOut = strOut & Chr(arrByte(j))
j = j + 2
Loop
Exit For ' we only want the first datasource
End If
Next i
Else
arrByte = Nz(DLookup("[NameMap]", "[MSYSNameMap]", "[Name] = '" & FormName & "'"), vbNullChar)
If UBound(arrByte) &LT; 4 Then Exit Function
strOut = ""
For j = 60 To UBound(arrByte) - 2 Step 2
If arrByte(j) = 0 And arrByte(j + 1) = 0 Then Exit For
strOut = strOut & Chr(arrByte(j))
Next j
End If
frmRecordSource_FromNameMap = strOut
Erase arrByte
End Function
If you use the RecordSource in (say) OpenRecordset or a DCOUNT function, I would advise you to encapsulate it in square brackets: you might get the name of a hidden query object saved from a 'SELECT' statement in the RecordSource, and that name will contain '~' tilde characters which need special handling.
And now, something extra that you didn't ask for, but other people will be looking for if they Googled their way here for 'MS Access RecordSource for a closed form':
Getting an MS-Access form's RecordSource, whether it's open or not
Most times, your form will be open. Problem is, you don't know that... And if it's a subform, it might not be visible in the Forms() collection. Worse, a form that's hosted as a subform might exist as multiple instances in several open forms.
Good luck with that, if you're looking to extract dynamic properties... Like filters, or the Record Source if it's set 'on the fly' by VBA.
Public Function GetForm(FormName As String, Optional ParentName As String = "") As Form
' Returns a form object, if a form with a name like FormName is open
' FormName can include wildcards.
' Returns Nothing if no matching form is open.
' Enumerates subforms in open forms, and returns the subform .form object if
' it has a matching name. Note that a form may be open as multiple instances
' if more than one subform hosts it; the function returns the first matching
' instance. Specify the named parent form (or the subform control's name) if
' you need to avoid an error arising from multiple instances of the form.
Dim objForm As Access.Form
If ParentName = "" Then
For Each objForm In Forms
If objForm.Name Like FormName Then
Set GetForm = objForm
Exit Function
End If
Next
End If
If GetForm Is Nothing Then
For Each objForm In Forms
Set GetForm = SearchSubForms(objForm, FormName, ParentName)
If Not GetForm Is Nothing Then
Exit For
End If
Next
End If
End Function
Private Function SearchSubForms(objForm As Access.Form, SubFormName As String, Optional ParentName As String = "") As Form
' Returns a Form object with a name like SubFormName, if the named object SubFormName is subform
' of an open form , or can be recursively enumerated as the subform of an open subform.
' This function returns the first matching Form: note that a form can be instantiated in multiple
' instances if it is used by more than one subform control.
Dim objCtrl As Control
For Each objCtrl In objForm
If TypeName(objCtrl) = "SubForm" Then
If objCtrl.Form.Name Like SubFormName Then
If ParentName = "" Or objForm.Name Like ParentName Or objCtrl.Name Like ParentName Then
Set SearchSubForms = objCtrl.Form
Exit For
End If
Else
Set SearchSubForms = SearchSubForms(objCtrl.Form, SubFormName, ParentName)
If Not SearchSubForms Is Nothing Then
Exit For
End If
End If
End If
Next objCtrl
End Function
Public Function FormRecordSource(FormName As String, Optional ParentName As String = "") As String
' Returns the Recordsource for a form, even if it isn't open in the Forms() collection
' This will look for open forms first. If you're looking for a subform, you may need a
' parent name for the form which hosts the subform: your named form might be open as a
' subform instance in more than one parent form.
' WARNING: there is a potential error here: if the form isn't open, and it has a blank
' RecordSource property, and it has one or more controls with a .RecordSource
' property populating a list, a list control's RecordSource could be returned
Dim objForm As Form
If FormName = "" Then
Exit Function
End If
Set objForm = GetForm(FormName, ParentName)
If objForm Is Nothing Then
FormRecordSource = FormRecordSource_FromNameMap(FormName)
Else
FormRecordSource = objForm.RecordSource
Set objForm = Nothing
End If
End Function
Share and enjoy: and please accept my apologies for any unwanted line breaks in the code sample.
One option would be to save the Record Source of the form as a Query. Say you have a form named [AgentForm] whose Record Source is
SELECT ID, AgentName FROM Agents
In your development .accdb copy of the database, open the form in Design View and open the Record Source in the Query Builder. Click the "Save As" button ...
and save the query as "AgentForm_RecordSource". Now the Record Source property of the form is just a reference to the saved query, and the query itself can be accessed directly through a QueryDef object. So, you could retrieve the SQL statement for the form's Record Source with
Dim cdb As DAO.Database, qdf As DAO.QueryDef, sql As String
Set cdb = CurrentDb
Set qdf = cdb.QueryDefs("AgentForm_RecordSource")
sql = qdf.SQL
or you could go ahead and open a Recordset with
Dim cdb As DAO.Database, qdf As DAO.QueryDef, rst As DAO.Recordset
Set cdb = CurrentDb
Set qdf = cdb.QueryDefs("AgentForm_RecordSource")
Set rst = qdf.OpenRecordset
If the form's Record Source is a SELECT statement rather than the name of a table or saved query, you can check the QueryDefs collection for the hidden QueryDef which Access created for that Record Source statement.
If it exists, you can check its .SQL property.
strFormName = "Form15"
? CurrentDb.QueryDefs("~sq_f" & strFormName).SQL
SELECT DISTINCTROW *
FROM [DB Audits];
You can trap error #3265, "Item not found in this collection", which will be thrown if that QueryDef does not exist.
Since you can't open your form in design view and opening your form regularly is causing performance issues, there are but a few more workarounds:
Depending on how you want to check for the closed form's recordsource, you can set a global variable in the following way, in a separate module:
Public glb_getrecordsource As String
Afterwards, depending on how you call the code, you can do the following:
Private Sub Command1_Click()
glb_getrecordsource = "Yes"
DoCmd.OpenForm "Form1"
'... Do something
End Sub
Then, as the final step, put the following at the beginning of your form's OnLoad event:
Private Sub Form_Load()
If glb_getrecordsource = "Yes" Then
glb_getrecordsource = Me.Form.RecordSource
DoCmd.Close acForm, "Form1", acSaveYes
Exit Sub
End If
'... Usual OnLoad events
End Sub
This will at least solve the performance issues, since you will not trigger any of the time consuming events, in the form's load event.
Another workaround:
You can export your form to a .txt file and then search the text file for the recordsource. The following code will export your forms to .txt files in a specified folder:
Dim db As Database
Dim d As Document
Dim c As Container
Dim sExportLocation As String
Set db = CurrentDb()
sExportLocation = "C:\AD\" 'Do not forget the closing back slash! ie: C:\Temp\
Set c = db.Containers("Forms")
For Each d In c.Documents
Application.SaveAsText acForm, d.Name, sExportLocation & "Form_" & d.Name & ".txt"
Next d
Code partly borrowed from this forum. Afterwards, you only have to open the file and search for the recordsource. If the recordsource is empty it will not be exported, so keep that in mind. Also, I doubt this will improve perfomance, but who knows!

expression to check if barcode input exists in which case load data for that barcode else continue to create new record

Hi I'm using Access 2007 and i am doing a program to enter stock items.
I am using a form and i need to make sure that when the user inputs the barcode of the product the system checks in the table if this exists. If it does exists, i need to load data for this existing item into the 3 additional fields in the same form, otherwise to continue creating the new record.
Now i am trying to use set tempvar in the beforeupdate however i cannot get it right.
any suggestions please.
field name : [barcode]
table to look into is "cartridge static data"
additional fields to fill if barcode exists are : [cartridge] , [end user] , [phone no]
Appreciate any help
regards
Tony
I would insert a combo box using the Access wizzard.
Select the data from "cartridge static data" i.e. [barcode] [cartridge] [end user] [phone no]
Do not hide the first row, and make sure you can see the data width in the wizard as you build it.
When completed go to the combo [data] [row source] and click the three {…}
Check what is displayed ~ for example sort by Barcode, remove nulls etc.
If you have the column widths wrong you can change those in the [format tab].
Column headers default to No which may need changing or you may be happy with that.
Under [other] name check you have a sane name e.g. cbo_barcode_search
Now attach this code to the AfterUpdate property of the Combo Box:
Sub cbo_barcode_search_AfterUpdate ()
Dim rs As DAO.Recordset
If Not IsNull(Me.cbo_barcode_search) Then
'Save before move.
If Me.Dirty Then
Me.Dirty = False
End If
'Search in the clone set.
Set rs = Me.RecordsetClone
rs.FindFirst "[BarCode] = " & Me.cbo_barcode_search
'rs.FindFirst "[BarCode] = """ & Me.cbo_barcode_search & """" 'for text
If rs.NoMatch Then
'Trigger new form or add the just typed data into your form as required
‘e.g. me.field1 = cbo_barcode_search.column(0) ' Barcode
Else
'Display the found record in the form.
' Usually use Me.Bookmark = rs.Bookmark but your question suggests this is not what you want so
'NOTE: First column data is column(0) NOT column(1)
me.field1 = cbo_barcode_search.column(0) ' Barcode
me.field2 = cbo_barcode_search.column(1) ' Cartridge
me.field3 = cbo_barcode_search.column(2) ' end user
me.field4 = cbo_barcode_search.column(3) ' phone no
End If
Set rs = Nothing
End If
End Sub
You will need to modify this to match your field names (eg me.field1 is probably me.barcode but it may be me.str_barcode ~ I don't know what you used.
Hope this gets you on the right track. Paul

Import MS Word form fields into MS Access

I have created an application form using MS Word and a whole bunch of form fields, and I have an Access db that can import all the data I need from this Word doc, thanks to this:
http://msdn.microsoft.com/en-us/library/aa155434%28office.10%29.aspx
Now everything works just fine (I even managed to get it to import into multiple tables!), but the problem with the above is that I have to manually enter the name of each file one at a time... which is fine if it's just a case of importing the application form as it comes in... but I have quite a lot sitting in a folder that needs entered into the database.
Then I found this:
How to show "Open File" Dialog in Access 2007 VBA?
I've tried to tweak and merge the two to make it work... but as you can guess, to no avail... (it doesn't help when I'm very much an Access novice!)
What I am looking to do is to be able to import a bunch of Word docs / form fields into MS Access by using the Open / Select file dialogue box... what I've got works, but I'd like to make it easier to work with!
Thanks everyone
Jake
##### Codes I been using
Option Compare Database
Option Explicit
Private Sub cmdFileDialog_Click()
' This requires a reference to the Microsoft Office 11.0 Object Library.
Dim fDialog As Office.FileDialog
Dim varFile As Variant
Dim appWord As Word.Application
Dim doc As Word.Document
' Dim cnn As New ADODB.Connection
' Dim rst As New ADODB.Recordset
Dim strDocName As String
Dim blnQuitWord As Boolean
' Clear the list box contents.
' Me.FileList.RowSource = ""
' Set up the File dialog box.
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
' Allow the user to make multiple selections in the dialog box.
.AllowMultiSelect = True
' Set the title of the dialog box.
.Title = "Select One or More Files"
' Clear out the current filters, and then add your own.
.Filters.Clear
.Filters.Add "Microsoft Word", "*.DOC"
.Filters.Add "All Files", "*.*"
' Show the dialog box. If the .Show method returns True, the
' user picked at least one file. If the .Show method returns
' False, the user clicked Cancel.
If .Show = True Then
' Loop through each file that is selected and then add it to the list box.
For Each varFile In .SelectedItems
' Me.FileList.AddItem varFile
Set appWord = GetObject(, "Word.Application")
Set doc = appWord.Documents.Open(varFile)
' cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
' "Data Source=M:\Medical\GPAppraisal\Contacts & Databases\" & _
' "AppForm.mdb;"
' rst.Open "tbl_Applicants", cnn, _
' adOpenKeyset, adLockOptimistic
' With rst
.addnew
!Title = doc.FormFields("wTitle").Result
!FirstName = doc.FormFields("wFirstName").Result
!LastName = doc.FormFields("wLastName").Result
!Address1 = doc.FormFields("wAddress1").Result
!Address2 = doc.FormFields("wAddress2").Result
!Address3 = doc.FormFields("wAddress3").Result
!City = doc.FormFields("wCity").Result
!PostCode = doc.FormFields("wPostCode").Result
!Email = doc.FormFields("wEmail").Result
!Phone1 = doc.FormFields("wPhone1").Result
!Phone2 = doc.FormFields("wPhone2").Result
!LM = doc.FormFields("wLM").Result
!LMAddress1 = doc.FormFields("wLMAddress1").Result
!LMAddress2 = doc.FormFields("wLMAddress2").Result
!LMAddress3 = doc.FormFields("wLMAddress3").Result
!LMCity = doc.FormFields("wLMCity").Result
!LMPostCode = doc.FormFields("wLMPostCode").Result
!LMEmail = doc.FormFields("wLMEmail").Result
!LMPhone = doc.FormFields("wLMPhone").Result
!LMOK = doc.FormFields("wLMOK").Result
!Probity = doc.FormFields("wProbity").Result
!Practising = doc.FormFields("wPractising").Result
!Signature = doc.FormFields("wSignature").Result
!AppDate = doc.FormFields("wAppDate").Result
!e2011012028 = doc.FormFields("w2011012028").Result
!e2011021725 = doc.FormFields("w2011021725").Result
!e2011030311 = doc.FormFields("w2011030311").Result
!e2011031625 = doc.FormFields("w2011031625").Result
!e20110203 = doc.FormFields("w20110203").Result
!e20110211 = doc.FormFields("w20110211").Result
!e20110322 = doc.FormFields("w20110322").Result
!e20110330 = doc.FormFields("w20110330").Result
.Update
.Close
End With
doc.Close
If blnQuitWord Then appWord.Quit
cnn.Close
MsgBox "Application Imported!"
Cleanup:
' Set rst = Nothing
' Set cnn = Nothing
Set doc = Nothing
Set appWord = Nothing
Next
Else
MsgBox "You clicked Cancel in the file dialog box."
End If
End With
End Sub
#
I've tried to mess with me.tables and me!forms and .add etc etc - obviously I'm a complete novice here!!!
What I want is to be able to import data from form fields in a Word Doc into a MS Access table (which I have managed to do with the first URL in my original post above); by means of selecting the Word doc from the Open/Select dialogue box, instead of manually entering the names of each Word doc.
My apologies if it sounds obvious or simple - Access is not my strong point by any means!
Before I begin I didn't understand why you have so many uncommented lines (lines beginnig mit ' ) in you code example. I assume that most of those lines would normally not bei uncommented and be part of the working code. Or are there artifacts of the Stack Overflow Editor?
I see a few problems, that might to guide you to a solution.
1) When you use
With fDialog
you let this 'open' until the end of the code (even using a second With in between). I would recommend to set you corresponding 'End With' right after you no longer require it. Remeber (or take note): The
With fDialog
[... something]
' Set the title of the dialog box.
.Title = "Select One or More Files"
is really just a shorthand for
fDialog.Title
(i.e. a "naked" . means, that it has to be appendend to the object in the With) so you could do away with the "With" entirely. IN you example I would set the "End With" right before
If .Show = True Then
and then use
If fDialog.Show = True Then
2) I would set
Set appWord = GetObject(, "Word.Application")
outside your For Each loop (don't forget to take Set appWord = Nothing outside the loop as well). Remember that with GetObject you need an runnig Word-instance, otherwise you might want to use
Set appWord = CreateObject("Word.Application")
or to have it both ways, try to get a Word-object, and if it is not available (i.e. Err.Number = 429) create a new one.
On Error Resume Next
Set appWord = GetObject(, "Word.Application")
If Err.Number = 429 Then
Set appWord = CreateObject("Word.Application")
End If
On Error GoTo 0
3) When working or at least while developping using automation I would always set
objword.Visible = True
so you see error messages or other problems right within Word.
HTH for the next steps (in case you have this problem anymore)
Andreas