![]() |
|
|
|
#1
|
|||
|
|||
|
Happy Easter (for those who celebrate it),
I have a question on how to proceed with my education. Below are the primary issues I need to learn how to perform. Final Objectives
That pretty much covers it. I already have a basic understanding of creating forms in MS Word using content controls (thanks to macropod, gmaxey and gmayor). My main issue seems to be finding information on accessing and modifying external data sources (i.e. MS Access db) in VBA. What I am looking for is an online resource/tutorials on how to perform the items listed above (with primary emphasis on Item #2). Any and all input is much appreciated. |
|
#2
|
||||
|
||||
|
There's a thread at http://answers.microsoft.com/en-us/o...6-8db862b6032c which demonstrates how to read an Access table into a list box, and a similar code example for Excel on my web site at http://www.gmayor.com/Userform_ComboBox.html
__________________
Graham Mayor - MS MVP (Word) (2002-2019) Visit my web site for more programming tips and ready made processes www.gmayor.com |
|
#3
|
|||
|
|||
|
Quote:
Quote:
Quote:
I'm ashamed to admit that I went through all three of your replies in exhaustive detail but I still don't seem to be getting it. For now I am just trying to use Excel as the data source. I tried to create a simple form with one list box control and a named range in excel with four values in the column. ![]() ![]() Code:
Sub InitializeDocument()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim NoOfRecords As Long
' Open the database
'Set db = OpenDatabase("C:\Temp\ItemSheet.xlsx", False, False, "Excel 12.0")
Set db = OpenDatabase("C:\Temp\ItemSheet.xlsx", False, False, "Excel 12.0; IMEX=1;")
' Retrieve the recordset
Set rs = db.OpenRecordset("SELECT * FROM ItemRange")
' Determine the number of retrieved records
With rs
.MoveLast
NoOfRecords = .RecordCount
.MoveFirst
End With
' Set the number of Columns = number of Fields in recordset
ListBox1.ColumnCount = rs.Fields.Count
' Load the ListBox with the retrieved records
ListBox1.Column = rs.GetRows(NoOfRecords)
' Cleanup
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
End Sub
Sorry for the never ending newbie questions.
|
|
#4
|
||||
|
||||
|
See also:
Fillable Forms Create a fillable form - Word Dependent Dropdown Content Controls https://www.msofficeforums.com/word-...html#post77762 Hierarchical Dropdown Content Controls https://www.msofficeforums.com/word-vba/29617-creating-reducing-drop-down-list.html#post94603 Dependent Text Content Controls https://www.msofficeforums.com/word-...html#post46903 Content Control conditional formatting https://www.msofficeforums.com/word-...html#post47254 Dropdown Content Control Population from Excel https://www.msofficeforums.com/word-...html#post46287 Creating Performance Assessments with Content Controls https://www.msofficeforums.com/word-...html#post33489 Adding Table Rows with Content Controls https://www.msofficeforums.com/word-...html#post87989 https://www.msofficeforums.com/word-...html#post38461 Replicating data in a form: http://gregmaxey.com/word_tip_pages/repeating_data.html Populating document bookmarks from a userform https://www.msofficeforums.com/word-...html#post76386 Saving with pre-defined names & read-only password protection is managed via the SaveAs2 method.
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
|
#5
|
|||
|
|||
|
Regarding #2. Often a document content control itself can serve as a pseudo external source for populating a userform listbox.
Private Sub UserForm_Initialize() Dim lngIndex As Long For lngIndex = 2 To ActiveDocument.SelectContentControlsByTitle("Lette r").Item(1).DropdownListEntries.Count ListBox1.AddItem ActiveDocument.SelectContentControlsByTitle("Lette r").Item(1).DropdownListEntries(lngIndex).Text Next End Sub |
|
#6
|
||||
|
||||
|
Well, for starters, your code is nothing like that found in any of the links I posted. The link under the heading 'Dropdown Content Control Population from Excel' above is all you need to populate a dropdown content control's text and the corresponding values from Excel. The other links mostly show how you might use content controls for other kinds of processing.
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
|
#7
|
|||
|
|||
|
Quote:
|
|
#8
|
||||
|
||||
|
Quote:
StrWkBkNm = "C:\Users\" & Environ("Username") & "\Documents\Workbook Name.xls" StrWkShtNm = "Sheet1" As coded, the macro expects the dropdown to be populated to be the first one in the document, but I'm sure you can see where you can change that in the code.
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
|
#9
|
|||
|
|||
|
Quote:
OK, I think I figured it out. I got the code to work but I have one final question... Code:
With xlWkBk.Worksheets(StrWkSht)
' Find the last-used row in column A.
LRow = .Cells(.Rows.Count, 1).End(xlUp).Row
' Populate the content control,
ActiveDocument.ContentControls(4).DropdownListEntries.Clear
For i = 1 To LRow
ActiveDocument.ContentControls(4).DropdownListEntries.Add Text:=Trim(.Range("A" & i)), Value:=Trim(.Range("B" & i))
Next
End With
Your input (and patience) is very much appreciated.
|
|
#10
|
||||
|
||||
|
Quote:
For i = 2 To LRow
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
|
#11
|
|||
|
|||
|
Code:
Option Explicit
Sub AutoOpen()
Dim oFrm As UserForm1
Set oFrm = New UserForm1
LoadFromExcel_ADODB oFrm.ListBox1, "D:\Book1.xlsx", "Sheet1"
oFrm.Show
End Sub
Sub LoadFromExcel_ADODB(ByRef oListPassed As Object, ByRef strSource As String, _
strRange As String, Optional bIsSheet As Boolean = True, _
Optional bSuppressHeadingRow As Boolean = False)
Dim oConn As Object
Dim oRecSet As Object
Dim strConnection As String
Dim lngCount As Long
If bIsSheet Then
strRange = strRange & "$]"
Else
strRange = strRange & "]"
End If
Set oConn = CreateObject("ADODB.Connection")
If bSuppressHeadingRow Then
'Suppress first row.
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & strSource & ";" & _
"Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
Else
'No suppression.
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & strSource & ";" & _
"Extended Properties=""Excel 12.0 Xml;HDR=NO"";"
End If
oConn.Open ConnectionString:=strConnection
Set oRecSet = CreateObject("ADODB.Recordset")
'Read the data from the worksheet/range.
oRecSet.Open "SELECT * FROM [" & strRange, oConn, 2, 1
With oRecSet
.MoveLast
'Get count.
lngCount = .RecordCount
.MoveFirst
End With
With oListPassed
'Load the records into the columns of the named list/combo box.
.ColumnCount = oRecSet.Fields.Count
.Column = oRecSet.GetRows(lngCount)
End With
'Cleanup
If oRecSet.State = 1 Then oRecSet.Close
Set oRecSet = Nothing
If oConn.State = 1 Then oConn.Close
Set oConn = Nothing
lbl_Exit:
Exit Sub
End Sub
|
|
#12
|
|||
|
|||
|
Why are you physically opening the Excel file in the first place?
I have already shown you once how to populate a userform listbox without opening Excel and excluding the column headings (optional) which you ignored. If you want to put the Excel column A content as the CC dropdown text and the column B content as the CC.Dropdown value then: Code:
Sub AutoOpen()
Dim varData As Variant
Dim lngIndex As Long
Dim oCC As ContentControl
varData = LoadFromExcel_ADODB("D:\Book1.xlsx", "Sheet1")
Set oCC = ActiveDocument.ContentControls(4) 'A very poor method.
'Use instead
'Set oCC = ActiveDocument.ContentControls("#########") 'ID
'or
'Set oCC = ActiveDocument.SelectContentControlsByTitle("Title").Item(#)
'Set oCC = ActiveDocument.SelectContentControlsByTag("Tag").Item(#)
With oCC
For lngIndex = .DropdownListEntries.Count To 2 Step -1
.DropdownListEntries(lngIndex).Delete
Next lngIndex
For lngIndex = 0 To UBound(varData, 2)
.DropdownListEntries.Add varData(0, lngIndex), varData(1, lngIndex)
Next lngIndex
End With
lbl_Exit:
Exit Sub
End Sub
Function LoadFromExcel_ADODB(ByRef strSource As String, _
strRange As String, Optional bIsSheet As Boolean = True, _
Optional bSuppressHeadingRow As Boolean = False)
Dim oConn As Object
Dim oRecSet As Object
Dim strConnection As String
Dim lngCount As Long
If bIsSheet Then
strRange = strRange & "$]"
Else
strRange = strRange & "]"
End If
Set oConn = CreateObject("ADODB.Connection")
If bSuppressHeadingRow Then
'Suppress first row.
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & strSource & ";" & _
"Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
Else
'No suppression.
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & strSource & ";" & _
"Extended Properties=""Excel 12.0 Xml;HDR=NO"";"
End If
oConn.Open ConnectionString:=strConnection
Set oRecSet = CreateObject("ADODB.Recordset")
'Read the data from the worksheet/range.
oRecSet.Open "SELECT * FROM [" & strRange, oConn, 2, 1
With oRecSet
.MoveLast
'Get count.
lngCount = .RecordCount
.MoveFirst
End With
LoadFromExcel_ADODB = oRecSet.GetRows(lngCount)
'Cleanup
If oRecSet.State = 1 Then oRecSet.Close
Set oRecSet = Nothing
If oConn.State = 1 Then oConn.Close
Set oConn = Nothing
lbl_Exit:
Exit Function
End Function
|
|
#13
|
|||
|
|||
|
Quote:
But macropod told me to! ![]() Just kidding. Now that you have thoroughly scolded me I will look at your example more closely. Please remember, newbie here, so mistakes will be varied and frequent. ![]() And I very much appreciate your input. |
|
|
|