简体   繁体   中英

Access VBA - Problems looping through fields in Access last record and exporting to Word bookmarks?

Thanks for looking at this.

I have a recordset with 60 fields and I want to export the last record for each field into a Microsoft Word file with 60 bookmarks called g1 to g60 .

Of course I would like to loop through these but can't make it work.

Essentially what I want is this:

Dim wApp As Word.Application
Dim wDoc As Word.Document
Dim wDoct As Word.Document
Dim rs As DAO.Recordset
Dim rng As Word.Range
Dim intI As Integer
Dim fld As DAO.field

Set wApp = New Word.Application
Set wDoc = wApp.Documents.Open("C:\Users\Peter\Documents\testdoc.docm", ReadOnly:=False)
Set wDoct = wApp.Documents.Open("C:\Users\Peter\Documents\Trends.docx")
Set rs = CurrentDb.OpenRecordset("Overall")

Set rs = CurrentDb.OpenRecordset("Grades")

If Not rs.EOF Then rs.MoveLast

wDoc.Bookmarks("g1").Range.Text = Nz(rs!PlanQ, "")
wDoc.Bookmarks("g2").Range.Text = Nz(rs!PlanQMin, "")
wDoc.Bookmarks("g3").Range.Text = Nz(rs!PlanUnsat, "")
wDoc.Bookmarks("g4").Range.Text = Nz(rs!BriefQ, "")
wDoc.Bookmarks("g5").Range.Text = Nz(rs!BriefQmin, "")
wDoc.Bookmarks("g6").Range.Text = Nz(rs!BriefUnsat, "")
' and so on up to 60
wDoct.Save
wApp.Quit

This works but needs to be looped of course - I tried this, but it errors out:

Dim wApp As Word.Application
Dim wDoc As Word.Document
Dim wDoct As Word.Document
Dim rs As DAO.Recordset
Dim rng As Word.Range
Dim intI As Integer
Dim fld As DAO.field

Set wApp = New Word.Application
Set wDoc = wApp.Documents.Open("C:\Users\Peter\Documents\testdoc.docm", ReadOnly:=False)
Set wDoct = wApp.Documents.Open("C:\Users\Peter\Documents\Trends.docx")
Set rs = CurrentDb.OpenRecordset("Overall")

Set rs = CurrentDb.OpenRecordset("Grades")

If Not rs.EOF Then rs.MoveLast

intI = 1

With rs
Do Until .EOF
For Each fld in rs.Fields
wDoc.Bookmarks("g" & "intI").Range.Text = Nz(rs!fld.Name, "")

Next fld
intI = intI + 1
loop
End With

wDoct.save
Wapp.quit

Any ideas will be very much welcome, otherwise I have a lot of typing ahead of me. :-)

Thank you for your time!

Peter

This is the current code that fail like mentioned below: UPDATE This is the exact copy paste.

Public Sub Looptest()

Dim wApp As Word.Application
Dim wDoc As Word.Document
Dim rs As DAO.Recordset
Dim index As Integer
Dim item As Variant

Set wApp = New Word.Application
Set wDoc = wApp.Documents.Open("C:\Users\Peter\Documents\testdoc.docm", ReadOnly:=False)

Set rs = CurrentDb.OpenRecordset("Grades")

If Not rs.EOF Then rs.MoveLast

For Each item In rs.Fields
    index = index + 1

    Dim bookmarkName As String
    bookmarkName = "g" & index

    Dim bookmarkValue As Variant
    bookmarkValue = Nz(rs(item.Name).Value, "")

    Debug.Print "Try set bookmark '" & bookmarkName & "' to '" & bookmarkValue & "' now."

    Dim bookmarkRange As Word.Range
    Set bookmarkRange = wDoc.Bookmarks(bookmarkName).Range

    bookmarkRange.Text = bookmarkValue

    Set bookmarkRange = Nothing
    Next item

wApp.DisplayAlerts = False
wDoc.SaveAs2 "C:\Users\Peter\Documents\" & rs!ID & "_gradesheet.docm"
wDoc.Close
wApp.Quit

This seems to be what you want:

Dim index As Integer
Dim item As Variant

For Each item In rs.Fields
    index = index + 1
    wDoc.Bookmarks("g" & index).Range.Text = Nz(rs(item.Name).Value, "")
Next item

It iterates the fields of the recordset and fills the bookmarks like you seem to want it.

What exactly error did you receive?

You should also check your code again, there are some superfluous fragments in it.

Update:

You get this error as I understand:

5941: The requested member of the collection does not exist.

Try this instead. It separates the functionality to single steps, enabling you to determine what the cause is:

  • It builds the new bookmark name
  • It retrieves the value to set to the bookmark
  • It prints out which bookmark now will be set to which value
  • It gets a reference to the bookmark to be set
  • It sets the bookmarks value

You should be able now to find out the reason for the error, by seeing which line of code breaks and what the values of the variables are.

    Dim index As Integer
    Dim item As Variant

    For Each item In rs.Fields
        If item.Name <> "ID" Then
            index = index + 1

            If index = 127 Then Exit For

            Dim bookmarkName As String
            bookmarkName = "g" & index

            Dim bookmarkValue As Variant
            bookmarkValue = Nz(rs(item.Name).Value, "")

            Debug.Print "Try set bookmark '" & bookmarkName & "' to '" & bookmarkValue & "' now."

            Dim bookmarkRange As Word.Range
            Set bookmarkRange = wDoc.Bookmarks(bookmarkName).Range

            bookmarkRange.Text = bookmarkValue

            Set bookmarkRange = Nothing
        End If
    Next item

Your code tries to match numbered bookmarks to table fields, based only on their order. Even if you get it to work now, this will be very hard to maintain, every change will cause new troubles.

It is much easier to name the bookmarks identical to their matching table field names, ie PlanQ etc.

Then your code becomes simpler and maintainable.
And if a table field (eg ID ) doesn't exist as bookmark in the document, you can simply ignore it.

For Each fld In rs.Fields

    Dim bookmarkName As String
    bookmarkName = fld.Name

    Dim bookmarkValue As String  ' since you are using Nz(), you don't need Variant
    bookmarkValue = Nz(fld.Value, "")

    If wDoc.Bookmarks.Exists(bookmarkName) Then
        wDoc.Bookmarks(bookmarkName).Range.Text = bookmarkValue
    Else
        Debug.Print "Ignored table field <" & bookmarkName & "> - no matching bookmark found in word document."
    End If

Next item

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM