code throwing error user-defined not defined - vba

code is below, Thanks all,
this function will create a word document
I updated the post, this was working good with 32-bit office, we upgraded to o365 64-bit and throwing error
Any suggestions would be great
Function ShipMerge_JMail(invNum As Long)
On Error GoTo ShipMergeErr
'Stop
Dim objWord As New Word.Application
'objWord.Visible = True
Dim objWordDoc As Word.Document
Set objWordDoc = objWord.Documents.Add(ShipMergeDot)
Dim temp1, temp, i As Integer, j As Integer
Dim DetailCount As Integer
Dim rstShipDetails As DAO.Recordset, rstFactory As DAO.Recordset, dbs As DAO.Database
Dim CellNames(5) As String, CellTest As Variant, PartTotal As Long
Dim SQL1 As String
Dim GTotal As Double 'Changed system to use sug retail as price
CellNames(1) = "[QTY]"
CellNames(2) = "[DESC]"
CellNames(3) = "[PN]"
CellNames(4) = "[Cost]"
CellNames(5) = "[comments]"
'CellNames(1) = "[QTY]"
'CellNames(2) = "[DESC]"
'CellNames(3) = "[PN]"
'CellNames(4) = "[QTY]"
'CellNames(5) = "[comments]"
SQL1 = ""
SQL1 = SQL1 + "SELECT DISTINCTROW tblShipingInfo.[To Field], "
SQL1 = SQL1 + "tblShipingInfo.From, tblShipingInfo.[Shipped VIA], tblShipingInfo.[QAH No], "
SQL1 = SQL1 + "tblShipingInfo.[Ship Date], tblShipingInfo.[report no] AS [QID #], "
SQL1 = SQL1 + "tblShipingInfo.[Invoice #], tblShipingInfo.[Atten], "
SQL1 = SQL1 + "tblShipping_Details.[Control Invoice #] AS [CI#], "
SQL1 = SQL1 + "tblShipping_Details.Qty, tblShipping_Details.Desc,tblShipping_Details.PN, "
SQL1 = SQL1 + "tblShipingInfo.[Fax Date],tblShipping_Details.cost , tblShipping_Details.Comments "
SQL1 = SQL1 + "FROM tblShipingInfo LEFT JOIN tblShipping_Details ON "
SQL1 = SQL1 + "tblShipingInfo.[Invoice #] = tblShipping_Details.[Control Invoice #]"
'SQL1 = SQL1 + ""
'SQL1 = SQL1 + ""
Set dbs = CurrentDb
Set rstFactory = dbs.OpenRecordset("qryFactories", dbOpenDynaset)
Set rstShipDetails = dbs.OpenRecordset(SQL1)
'change to docx 6 mar 2015
objWordDoc.SaveAs Filename:="c:\temp\shipinv.docx"
'objWordDoc.PrintOut Background:=True
objWord.Options.BackgroundSave = True
While objWord.BackgroundSavingStatus > 0
' Wait for Word to finish Saving
DoEvents
Wend
'While objWord.BackgroundPrintingStatus > 0
' Wait for Word to finish printing.. can use the backgroundsave status later....
' DoEvents
'Wend
DoEvents
'rstShipDetails.Filter = "[Invoice #]= 671"
'rstShipDetails.Filter = "[Invoice #]= 1072"
rstShipDetails.Filter = "[Invoice #]= " & invNum
rstShipDetails.MoveFirst
Set rstShipDetails = rstShipDetails.OpenRecordset
DetailCount = rstShipDetails.RecordCount
If DetailCount = 0 Then GoTo NoRecords
rstShipDetails.MoveLast
DetailCount = rstShipDetails.RecordCount
rstShipDetails.MoveFirst
rstFactory.Filter = "[Factory ID]= '" & rstShipDetails![To Field] & "'"
Set rstFactory = rstFactory.OpenRecordset
rstFactory.MoveLast
Dim mAtten As String
mAtten = Space(1)
'if no info in the table for attention field use the default factory to info
mAtten = IIf(IsNull(rstShipDetails![Atten]), rstFactory![Atten], rstShipDetails![Atten])
Dim newrow As Word.Row
'SELECT DISTINCTROW tblShipingInfo.[To Field], tblShipingInfo.From, tblShipingInfo.[Shipped VIA], tblShipingInfo.[Ship Date], tblShipingInfo.[report no] AS [QID #], tblShipingInfo.[Invoice #], tblShipping_Details.[Control Invoice #] AS [CI#], tblShipping_Details.Qty, tblShipping_Details.Desc, tblShipping_Details.PN, tblShipingInfo.[Fax Date], tblShipping_Details.Comments
'FROM tblShipingInfo LEFT JOIN tblShipping_Details ON tblShipingInfo.[Invoice #] = tblShipping_Details.[Control Invoice #];
If DetailCount > 1 Then
For i = 1 To DetailCount - 1
Set newrow = objWordDoc.Tables(1).Rows.Add(BeforeRow:=objWordDoc.Tables(1).Rows(2))
Next
End If
For i = 1 To DetailCount
'Fill out the table
With objWordDoc.Tables(1).Rows(i + 1)
Dim c
j = 1
'For Each c In .Cells
' CellTest = rstShipDetails(CellNames(j))
' Select Case j
' Case 1 ' qty
' PartTotal = PartTotal + Val(CellTest)
' Case 4 'total price
' CellTest = "$" & CellTest & ".00"
' End Select
' If Not IsNull(CellTest) Then
' c.Range.InsertAfter Nz(CellTest, "")
' End If
'
' j = j + 1
'Next c
For Each c In .Cells 'new cost system
CellTest = rstShipDetails(CellNames(j))
Select Case j
Case 1 ' qty
PartTotal = Val(CellTest)
Case 4 'total price
CellTest = "$" & Round(((CellTest * PartTotal) * 0.5), 2)
GTotal = GTotal + CellTest 'collect the total price of parts
End Select
If Not IsNull(CellTest) Then 'put the value in the table
c.Range.InsertAfter Nz(CellTest, "")
End If
j = j + 1
Next c
End With
rstShipDetails.MoveNext
Next
Dim location
rstShipDetails.MoveFirst
objWord.Selection.GoTo what:=wdGoToBookmark, Name:="GrandTotal"
objWord.Selection.InsertAfter "$" & GTotal
'objWord.Selection.GoTo what:=wdGoToBookmark, Name:="Atten"
'objWord.Selection.InsertAfter mAtten
'objWord.Selection.GoTo what:=wdGoToBookmark, Name:="CompanyName"
'objWord.Selection.InsertAfter rstFactory![Compay Name]
'objWord.Selection.GoTo what:=wdGoToBookmark, Name:="FactoryCity"
'objWord.Selection.InsertAfter rstFactory![City]
'objWord.Selection.GoTo what:=wdGoToBookmark, Name:="FactoryCountryZip"
'objWord.Selection.InsertAfter rstFactory![Country] & ", " & rstFactory![zip]
'objWord.Selection.GoTo what:=wdGoToBookmark, Name:="FactoryID"
'objWord.Selection.InsertAfter rstShipDetails![To Field]
'objWord.Selection.GoTo what:=wdGoToBookmark, Name:="FactoryName"
'objWord.Selection.InsertAfter rstFactory![Factory Name]
'objWord.Selection.GoTo what:=wdGoToBookmark, Name:="FactoryProvidence"
'objWord.Selection.InsertAfter rstFactory![Providence]
'objWord.Selection.GoTo what:=wdGoToBookmark, Name:="FactoryStreet"
'objWord.Selection.InsertAfter rstFactory![Street]
objWord.Selection.GoTo what:=wdGoToBookmark, Name:="InvNum"
objWord.Selection.InsertAfter Format(rstShipDetails![Invoice #], "00000")
objWord.Selection.GoTo what:=wdGoToBookmark, Name:="ShipDate"
objWord.Selection.InsertAfter Nz(rstShipDetails![Ship Date], "")
'use text box instead of bookmarks 6 mar 2015
Dim mADD As String
mADD = ""
mADD = mADD & rstFactory![Compay Name] & vbNewLine
mADD = mADD & rstShipDetails![To Field] & vbNewLine
mADD = mADD & rstFactory![Street] & vbNewLine
mADD = mADD & rstFactory![City] & vbNewLine
mADD = mADD & rstFactory![Providence] & vbNewLine
mADD = mADD & rstFactory![Country] & ", " & rstFactory![zip] & vbNewLine
mADD = mADD & rstFactory![Compay Name] & vbNewLine
objWord.ActiveDocument.Shapes("Rectangle 2").TextFrame.TextRange.Text = mADD
'objWord.Selection.GoTo what:=wdGoToBookmark, Name:="QIDNum"
'objWord.Selection.InsertAfter Nz(rstShipDetails![QID #], "None")
Dim QAHNo As Variant
'QAHNo = DLookup("[QAH #]", "qid report", "[Report Number:]= '" & rstShipDetails![QID #] & "'")
QAHNo = Nz(rstShipDetails![QAH No], "None")
'objWord.Selection.GoTo what:=wdGoToBookmark, Name:="QAHNo"
'objWord.Selection.InsertAfter QAHNo
objWord.ActiveDocument.Shapes("Text Box 9").TextFrame.TextRange.Text = "QAH/QIS/QIC No.: " & vbNewLine & QAHNo
objWord.ActiveDocument.Shapes("Text Box 10").TextFrame.TextRange.Text = "Attention: " & mAtten
objWordDoc.Save
objWordDoc.Close wdDoNotSaveChanges
DoCmd.Hourglass True
Set rstShipDetails = Nothing
Set rstFactory = Nothing
Set dbs = Nothing
objWord.Quit
Set objWordDoc = Nothing
Set objWord = Nothing
DoCmd.Hourglass False

Related

Microsoft Access VBA Run Time Syntax Error for SQL Query

Here is my updated code per #Parfait suggestion. It still isn't working, getting the following error:
Run-time error '3421'
Data type conversion error
On the following line: Set rec = qdef.OpenRecordset(strQry)
Option Compare Database
Private Sub Command0_Click()
Dim db As DAO.Database
Dim qdef As DAO.QueryDef
Dim rec As DAO.Recordset
Dim olApp As Object
Dim olItem As Variant
Dim strQry As String
Dim aHead(1 To 4) As String
Dim aRow(1 To 4) As String
Dim aBody() As String
Dim lCnt As Long
'Prepared Statement No Data
strQry = "PARAMETERS cboParam TEXT(255);" _
& " SELECT [Loan ID], [Prior Loan ID], [SRP Rate], [SRP Amount] " _
& " FROM emailtable " _
& " WHERE [Seller Name:Refer to As] = [cboParam]"
Set db = CurrentDb
Set qdef = db.CreateQueryDef("", strQry)
' BIND PARAMETER
qdef!cboParam = Me.Combo296
' OPEN RECORDSET
Set rec = qdef.OpenRecordset(strQry)
'Create the header row
aHead(1) = "Loan ID"
aHead(2) = "Prior Loan ID"
aHead(3) = "SRP Rate"
aHead(4) = "SRP Amount"
lCnt = 1
ReDim aBody(1 To lCnt)
aBody(lCnt) = "<HTML><body><table border='2'><tr><th>" & Join(aHead, "</th><th>") & "</th></tr>"
If Not (rec.BOF And rec.EOF) Then
Do While Not rec.EOF
lCnt = lCnt + 1
ReDim Preserve aBody(1 To lCnt)
aRow(1) = rec("[Loan ID]")
aRow(2) = rec("[Prior Loan ID]")
aRow(3) = rec("[SRP Rate]")
aRow(4) = rec("[SRP Amount]")
aBody(lCnt) = "<tr><td>" & Join(aRow, "</td><td>") & "</td></tr>"
rec.MoveNext
Loop
End If
aBody(lCnt) = aBody(lCnt) & "</table></body></html>"
Set objOutlook = CreateObject("Outlook.Application")
Set objMail = objOutlook.CreateItem(0)
With objMail
.Display 'To display message
.To = Me.Combo88
.cc = Me.Combo282
.Subject = "*SECURE* " & Me.Combo296 & " Refund Request (" & Me.Combo212 & " " & Me.Combo284 & ")"
.HTMLBody = "<p><font face=""calibri"" style=""font-size:11pt;"">Greetings,</p>" _
& "<p>We recently acquired loans from " & Me.Combo296 & ", some of which have paid in full and meet the criteria for early prepayment defined in the governing documents. We are requesting a refund of the SRP amount detailed on the attached list.</p>" _
& "<p>Please wire funds to the following instructions:</p>" _
& "<ul>Bank Name: My Bank</ul>" _
& "<ul>ABA: 1111111</ul>" _
& "<ul>Credit To: ABC Mortgage</ul>" _
& "<ul>Acct: 11111111111</ul>" _
& "<ul>Description: " & Combo296 & " EPO SRP Refund</ul>" _
& "<p>Thank you for the opportunity to service loans from " & Me.Combo296 & "! We appreciate your partnership.</p>" _
& "<p>If you have any questions, please contact your Relationship Manager, " & Me.Combo336 & " (Cc'd).</p>" _
& "<p><br>Sincerely,</br>" _
& "<br>Acquisitions</br>" _
& "<br>acquisitions#us.com</br></p>"
End With
rec.Close
Set rec = Nothing: Set qdef = Nothing: Set db = Nothing
End Sub
Any help would be greatly appreciated.
Avoid concatenating VBA data to SQL even HTML strings. Instead, consider the industry standard of SQL parameterization.
Dim db DAO.Database, qdef As DAO.QueryDef, rec AS DAO.Recordset
' PREPARED STATEMENT (NO DATA)
strQry = "PARAMETERS cboParam TEXT(255);" _
& " SELECT [Loan ID], [Prior Loan ID], [SRP Rate], [SRP Amount] " _
& " FROM emailtable " _
& " WHERE [Seller Name:Refer to As] = [cboParam]"
Set db = CurrentDb
Set qdef = db.CreateQueryDef("", strQry)
' BIND PARAMETER
qdef!cboParam = Me.Combo296
' OPEN RECORDSET
Set rec = qdef.OpenRecordset()
... ' REST OF CODE USING rec
rec.Close
Set rec = Nothing: Set qdef = Nothing: Set db = Nothing
Also, consider saving the email message HTML markup as a text in the table or as text box on form with placeholders to be replaced with combo box values:
.HTMLBody = Replace(Replace(Me.EmailMessage, "placeholder1", Me.Combo296),
"placeholder2", Me.Combo336)
I'm guessing (from your photo) that the data type of your [Seller Name:Refer to as] column is supposed to be string? In which case, your query is missing quotes to denote the string value in your comparison:
'Create each body row
strQry = "Select * from emailtable where [Seller Name:Refer to As] = """ & Me.Combo296 & """"
Set db = CurrentDb
Set rec = CurrentDb.OpenRecordset(strQry)

Loop Access error 424 Loop rs to excel

rivate Sub CmdOpenCmtList_Click()
On Error GoTo SubError
Dim xlApp As Excel.Application
Dim xlWkb As Excel.Workbook
Dim xlWks As Excel.Worksheet
Dim i As Integer 'First Row: CmtAwd
Dim j As Integer 'First Row: CmtJaws
Dim k As Integer 'First Row: CmtSick
Dim l As Integer 'Second Row: CmtCust
Dim m As Integer 'Second Row: CmtJun
Dim n As Integer 'Second Row: CmtMain
Dim SQLCmtAwd As String
'Dim SQLCmtAwdChair As String 'no chairman
Dim SQLCmtJaws As String
Dim SQLCmtJawsChair As String
Dim SQLCmtSick As String
Dim SQLCmtSickChair As String
Dim SQLCmtCust As String
Dim SQLCmtCustChair As String
Dim SQLCmtJun As String
Dim SQLCmtJunChair As String
Dim SQLCmtMain As String
Dim SQLCmtMainChair As String
Dim rsCmtAwd As DAO.Recordset
'Dim rsCmtAwdChair As DAO.Recordset 'no chairmen
Dim rsCmtJaws As DAO.Recordset
Dim rsCmtJawsChair As DAO.Recordset
Dim rsCmtSick As DAO.Recordset
Dim rsCmtSickChair As DAO.Recordset
Dim rsCmtCust As DAO.Recordset
Dim rsCmtCustChair As DAO.Recordset
Dim rsCmtJun As DAO.Recordset
Dim rsCmtJunChair As DAO.Recordset
Dim rsCmtMain As DAO.Recordset
Dim rsCmtMainChair As DAO.Recordset
SQLCmtAwd = "SELECT [FirstName] & "" "" & [LastName] AS FullName, TblMembers.CmtAwd, TblMembers.CmtAwd " & _
" FROM TblMembers " & _
" WHERE (((TblMembers.CmtAwd)=True))"
'SQLCmtAwdChair = " SELECT [FirstName] & "" "" & [LastName] AS FullName, TblMembers.CmtAwdChair, [FullName] & "" - Chairman"" AS FullNameChair " & _
' " FROM TblMembers " & _
' " WHERE (((TblMembers.CmtAwdChair)=True))"
SQLCmtJaws = "SELECT [FirstName] & "" "" & [LastName] AS FullName, TblMembers.CmtJaws " & _
" FROM TblMembers " & _
" WHERE (((TblMembers.CmtJaws)=True))"
SQLCmtJawsChair = " SELECT [FirstName] & "" "" & [LastName] AS FullName, TblMembers.CmtJawsChair, [FullName] & "" - Chairman"" AS FullNameChair " & _
" FROM TblMembers " & _
" WHERE (((TblMembers.CmtJawsChair)=True))"
SQLCmtSickChair = " SELECT [FirstName] & "" "" & [LastName] AS FullName, TblMembers.CmtSickChair, [FullName] & "" - Chairman"" AS FullNameChair " & _
" FROM TblMembers " & _
" WHERE (((TblMembers.CmtSickChair)=True))"
SQLCmtSick = "SELECT [FirstName] & "" "" & [LastName] AS FullName, TblMembers.CmtSickChair " & _
" FROM TblMembers " & _
" WHERE (((TblMembers.CmtSick)=True))"
SQLCmtCustChair = " SELECT [FirstName] & "" "" & [LastName] AS FullName, TblMembers.CmtCustChair, [FullName] & "" - Chairman"" AS FullNameChair " & _
" FROM TblMembers " & _
" WHERE (((TblMembers.CmtCustChair)=True))"
SQLCmtCust = "SELECT [FirstName] & "" "" & [LastName] AS FullName, TblMembers.CmtCust " & _
" FROM TblMembers " & _
" WHERE (((TblMembers.CmtCust)=True))"
SQLCmtJunChair = " SELECT [FirstName] & "" "" & [LastName] AS FullName, TblMembers.CmtJunChair, [FullName] & "" - Chairman"" AS FullNameChair " & _
" FROM TblMembers " & _
" WHERE (((TblMembers.CmtJunChair)=True))"
SQLCmtJun = "SELECT [FirstName] & "" "" & [LastName] AS FullName, TblMembers.CmtJun " & _
" FROM TblMembers " & _
" WHERE (((TblMembers.CmtJun)=True))"
SQLCmtMainChair = " SELECT [FirstName] & "" "" & [LastName] AS FullName, TblMembers.CmtMainChair, [FullName] & "" - Chairman"" AS FullNameChair " & _
" FROM TblMembers " & _
" WHERE (((TblMembers.CmtMainChair)=True))"
SQLCmtMain = "SELECT [FirstName] & "" "" & [LastName] AS FullName, TblMembers.CmtMainChair " & _
" FROM TblMembers " & _
" WHERE (((TblMembers.CmtMain)=True))"
Set rsCmtAwd = CurrentDb.OpenRecordset(SQLCmtAwd, dbOpenSnapshot)
'Set rsCmtAwdChair = CurrentDb.OpenRecordset(SQLCmtAwdChair, dbOpenSnapshot)
Set rsCmtJaws = CurrentDb.OpenRecordset(SQLCmtJaws, dbOpenSnapshot)
Set rsCmtJawsChair = CurrentDb.OpenRecordset(SQLCmtJawsChair, dbOpenSnapshot)
Set rsCmtSick = CurrentDb.OpenRecordset(SQLCmtSick, dbOpenSnapshot)
Set rsCmtSickChair = CurrentDb.OpenRecordset(SQLCmtSickChair, dbOpenSnapshot)
Set rsCmtCust = CurrentDb.OpenRecordset(SQLCmtCust, dbOpenSnapshot)
Set rsCmtCustChair = CurrentDb.OpenRecordset(SQLCmtCustChair, dbOpenSnapshot)
Set rsCmtJun = CurrentDb.OpenRecordset(SQLCmtJun, dbOpenSnapshot)
Set rsCmtJunChair = CurrentDb.OpenRecordset(SQLCmtJunChair, dbOpenSnapshot)
Set rsCmtMain = CurrentDb.OpenRecordset(SQLCmtMain, dbOpenSnapshot)
Set rsCmtMainChair = CurrentDb.OpenRecordset(SQLCmtMainChair, dbOpenSnapshot)
Set xlApp = New Excel.Application
Set xlWkb = xlApp.Workbooks.Open(CurrentProject.Path & "\Master\CommitteeList.xlsx")
Set xlWks = xlWkb.Sheets("Sheet1")
xlApp.Visible = True
i = 10 'First Row: CmtAwd
j = 10 'First Row: CmtJaws
k = 10 'First Row: CmtSick
With xlWks
Do While Not rsCmtAwdChair.EOF
.Range("E9").Value = (rsCmtAwdChair!FullNameChair)
rsCmtAwdChair.MoveNext
Loop
End With
With xlWks
Do While Not rsCmtAwd.EOF
.Range("E" & i - 1).Value = Nz(rsCmtAwd!FullName, "")
i = i + 1
rsCmtAwd.MoveNext
Loop
End With
With xlWks
Do While Not rsCmtJawsChair.EOF
.Range("Y9").Value = (rsCmtJawsChair!FullNameChair)
rsCmtJawsChair.MoveNext
Loop
End With
With xlWks
Do While Not rsCmtJaws.EOF
.Range("Y" & j).Value = Nz(rsCmtJaws!FullName, "")
j = j + 1
rsCmtJaws.MoveNext
Loop
End With
With xlWks
Do While Not rsCmtSickChair.EOF
.Range("AS9").Value = (rsCmtSickChair!FullNameChair)
rsCmtSickChair.MoveNext
Loop
End With
With xlWks
Do While Not rsCmtSick.EOF
.Range("AS" & k).Value = Nz(rsCmtSick!FullName, "")
k = k + 1
rsCmtSick.MoveNext
Loop
End With
With xlWks
Do While Not rsCmtCustChair.EOF
.Range("E16").Value = (rsCmtCustChair!FullNameChair)
rsCmtCustChair.MoveNext
Loop
End With
With xlWks
Do While Not rsCmtCust.EOF
.Range("AS" & i).Value = Nz(rsCmtCust!FullName, "")
i = i + 17
rsCmtSick.MoveNext
Loop
End With
With xlWks
Do While Not rsCmtJunChair.EOF
.Range("Y16").Value = (rsCmtJunChair!FullNameChair)
rsCmtJunChair.MoveNext
Loop
End With
With xlWks
Do While Not rsCmtJun.EOF
.Range("Y" & m).Value = Nz(rsCmtJun!FullName, "")
m = m + 1
rsCmtSick.MoveNext
Loop
End With
With xlWks
Do While Not rsCmtMainChair.EOF
.Range("AS16").Value = (rsCmtMainChair!FullNameChair)
rsCmtMainChair.MoveNext
Loop
End With
With xlWks
Do While Not rsCmtMain.EOF
.Range("Y" & n).Value = Nz(rsCmtMain!FullName, "")
n = n + 1
rsCmtMain.MoveNext
Loop
End With
SubExit:
On Error Resume Next
rsCmtAwd.Close
'rsCmtAwdChair.Close
rsCmtJaws.Close
rsCmtJawsChair.Close
rsCmtSick.Close
rsCmtSickChair.Close
rsCmtCust.Close
rsCmtCustChair.Close
rsCmtJun.Close
rsCmtJunChair.Close
rsCmtMain.Close
rsCmtMainChair.Close
Set rsCmtAwd = Nothing
'Set rsCmtAwdChair = Nothing
Set rsCmtJaws = Nothing
Set rsCmtJawsChair = Nothing
Set rsCmtSick = Nothing
Set rsCmtSickChair = Nothing
Set rsCustAwd = Nothing
Set rsCmtCustChair = Nothing
Set rsCmtJun = Nothing
Set rsCmtJunChair = Nothing
Set rsCmtMain = Nothing
Set rsCmtSickMain = Nothing
Exit Sub
SubError:
MsgBox "Error Number: " & Err.Number & "=" & Err.Description, vbCritical + vbOKOnly, "An error occured"
GoTo SubExit
End Sub
Is there a better way to do this. I solved my previous problem, but now I get an error of 424 object required. Before the object error I was getting no record error, I checked the queries all return records.
Is there a better way to loop thru rs and get the output to the excel file, I have about 18 committes that need to have a chairman and 1-5 members. Cells on excel ie... Y16 for Chairman and then in y17 the list of members.
1-
Instead of looping, you can use 'CopyfromRecordSet'. You just need to select the starting cell on each sheet of your Excel file, and the system do the rest.
I give you the Microsoft link:https://msdn.microsoft.com/en-us/library/office/aa223845(v=office.11).aspx
2-
On the 424 Object required problem, did you try to debug the code to find out which line the error occurs?
Hope this can help!

Checkboxes for taking input for a sql query in VBA (userform-excel)

I am trying to create a userform - which will have checkboxes for different years and command buttons for different queries. So if for example a user choses three checkboxes -1990,1993, 1995 and then the user clicks on a particular query. Then that query must be executed with that year in going into the "where part of that query"
This is my code :-
*
Private Sub CommandButton1_Click()
Dim connection As New ADODB.connection
Dim rst As New Recordset
Dim strConnectionStr As String
Dim Qry As String
strConnectionStr = "Provider=SQLOLEDB;" & "DATA SOURCE=" & _
"INITIAL CATALOG=;" & _
"UID=; PWD="
Qry = " SELECT d.Year,d.[University name],d.[School name], COUNT(distinct d.Title) 'Number of paper published'from [dbo].[Ashish$] d where [Business/Non-business]='1'group by d.Year,d.[University name],d.[School name] order by d.[Year], [Number of paper published] desc;"
ActiveSheet.Cells.ClearContents
connection.Open strConnectionStr
rst.Open Qry, connection
For iCols = 0 To rst.Fields.Count - 1
Sheets("Query1").Cells(1, iCols + 1).Value = rst.Fields(iCols).Name
Next
Sheets("Query1").Range("A2").CopyFromRecordset rst*`
rst.Close
connection.Close
End Sub
Above is the code for normal command buttons without check box . Below is the code for taking user inputs by checkboxes ...
Private Sub CommandButton1_Click()
Dim connection As New ADODB.connection
Dim rst As New Recordset
Dim strConnectionStr As String
Dim Qry As String
Dim ctl As Control
Dim i As Integer
i = 0
strConnectionStr = "Provider=SQLOLEDB;" & "DATA SOURCE=;" & _
"INITIAL CATALOG=;" & _
"UID=; PWD="
If CheckBox6.Value = True Then
year1 = CheckBox6.Caption
i = i + 1
End If
If CheckBox5.Value = True Then
year2 = CheckBox5.Caption
i = i + 1
End If
Qry = " SELECT d.Year,d.[University name],d.[School name], COUNT(distinct d.Title) 'Number of paper published'from [dbo].[Ashish$] d where [Business/Non-business]='1' and d.Year=CheckBox6.Caption group by d.Year,d.[University name],d.[School name] order by d.[Year], [Number of paper published] desc;"
ActiveSheet.Cells.ClearContents
connection.Open strConnectionStr
rst.Open Qry, connection
For iCols = 0 To rst.Fields.Count - 1
Sheets("Query1").Cells(1, iCols + 1).Value = rst.Fields(iCols).Name
Next
Sheets("Query1").Range("A2").CopyFromRecordset rst
rst.Close
connection.Close
End Sub
ub
Basically I am unable to take values from checkboxes and use them inside query statement for the purpose.
I need help . Can anyone guide me on this?
edit: the following was originally posted as an answer:
If CheckBox1.Value = True Then
y1 = CheckBox1.Caption
i = i + 1
End If
If CheckBox2.Value = True Then
y2 = CheckBox2.Caption
i = i + 1
End If
If CheckBox3.Value = True Then
x1 = CheckBox3.Caption
j = j + 1
End If
If CheckBox4.Value = True Then
x2 = CheckBox4.Caption
j = j + 1
End If
If CheckBox5.Value = True Then
x3 = CheckBox5.Caption
j = j + 1
End If
If i = 0 Then
MsgBox "Select at least one year "
End If
If j = 0 Then
MsgBox "Select at least one journal "
End If
strConnectionStr = "Provider=SQLOLEDB;" & "DATA SOURCE=;" & _
"INITIAL CATALOG=;" & _
"UID=; PWD="
Qry = " SELECT d.Year,d.[University name],d.[School name], COUNT(distinct d.Title) 'Number of paper published'from [dbo].[Ashish$] d where [Business/Non-business]='1' and "
Qry = Qry & "[Year] IN (" & y1 & "," & y2 & ") and [Name] IN (" & x3 & "," & x4 & ") & vbCrLf"
Qry = Qry & "group by d.Year,d.[University name],d.[School name] order by d.[Year], [Number of paper published] desc;"
ActiveSheet.Cells.ClearContents
connection.Open strConnectionStr
rst.Open Qry, connection
For iCols = 0 To rst.Fields.Count - 1
Sheets("Query1").Cells(1, iCols + 1).Value = rst.Fields(iCols).Name
Next
Sheets("Query1").Range("A2").CopyFromRecordset rst
rst.Close
connection.Close
End Sub
Above is my code and the question is posted in my last comment
It's as simple as ...and d.Year=" & CheckBox6.Caption & " group by...
If you want to use the value of a variable then it has to be outside of the double quotes. You can then use the & operator to join the pieces back together.
BUT: constructing an SQL query from user input by joining strings together is asking for trouble. SQL injection can be a very real possibility - see here and here
You can use an ADODB Command object in conjunction with the Parameters collection to execute a paramaterized query in a safe manner. See this answer for a demonstration of how to do so
edit: if some of the values are text strings then they should be enclosed in single quotes like this:
and [Name] IN ('" & x3 & "','" & x4 & "')
which will produce output like this:
and [Name] IN ('Academy of Science','Foo')
If only some of the variables might have values then you need to construct the IN clause differently:
Dim yearsChosen As String
If CheckBox1.Value = True Then
yearsChosen = yearsChosen & "," & CheckBox1.Caption
i = i + 1
End If
If CheckBox2.Value = True Then
yearsChosen = yearsChosen & "," & CheckBox2.Caption
i = i + 1
End If
' Check to see if anything was selected - if it was, remove the
' leading comma and add the AND [Year] IN part
If Len(yearsChosen <> 0) Then
yearsChosen = " AND [Year] IN (" & Mid$(yearsChosen, 2) & ")"
End If
The Names part would work similarly except you need single quotes around the values:
namesChosen = namesChosen & ",'" & CheckBox5.Caption & "'"
Building the SQL query is quite simple:
Qry = " SELECT d.Year,d.[University name],d.[School name], COUNT(distinct d.Title) 'Number of paper published'from [dbo].[Ashish$] d where [Business/Non-business]='1' "
Qry = Qry & yearsChosen & namesChosen & vbCrLf
Qry = Qry & "group by d.Year,d.[University name],d.[School name] order by d.[Year], [Number of paper published] desc;"

UDF function in Excel running ACE SQL query, JOIN two tables does not work

I am trying to figure out what wrong may be with a function in Excel that tries to join two tables. I presume the error is somewhere in SQL string.
The function works well without a join, returning correctly a table to an array - range of cells. ie when strSQL is only "SELECT * FROM [" & currAddress & "] "
It does not work when the string contains a join, ie strSQL = "SELECT * FROM [" & currAddress & "] " & _
"LEFT JOIN [" & currAddress2 & "] ON [Indeks].[" & currAddress & "] = [Indeks2].[" & currAddress2 & "];"
Here is my code, thank you for help:
Function SQL(dataRange As Range, dataRange2 As Range) As Variant
Application.Volatile
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim currAddress, currAddress2 As String
Dim varHdr, varDat, contentOut As Variant
Dim nc, nr, i, j As Long
SQL = Null
currAddress = ActiveSheet.Name & "$" & dataRange.Address(False, False)
Debug.Print currAddress
currAddress2 = ActiveSheet.Name & "$" & dataRange2.Address(False, False)
Debug.Print currAddress2
strFile = ThisWorkbook.FullName
strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFile _
& ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=0"";"
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
rs.CursorLocation = adUseClient ' required to return the number of rows correctly
cn.Open strCon
strSQL = "SELECT * FROM [" & currAddress & "] " & _
"LEFT JOIN [" & currAddress2 & "] ON [Indeks].[" & currAddress & "] = [Indeks2].[" & currAddress2 & "];"
Debug.Print strSQL
rs.Open strSQL, cn
'Check if recordset is empty
If rs.EOF Then
MsgBox "Function does not return any values"
SQL = ""
Exit Function
End If
' Process Column Headings
nc = rs.Fields.Count
ReDim varHdr(nc - 1, 0)
For i = 0 To rs.Fields.Count - 1
varHdr(i, 0) = rs.Fields(i).Name
Next
' Get Rows from the Recordset
nr = rs.RecordCount
varDat = rs.GetRows
' Combing Header and Data and Transpose
ReDim contentOut(0 To nr, 0 To nc - 1)
For i = 0 To nc - 1
contentOut(0, i) = varHdr(i, 0)
Next
For i = 1 To nr
For j = 0 To nc - 1
contentOut(i, j) = varDat(j, i - 1)
Next
Next
' Optional solution: Write Output Array to Sheet2
' With Sheet2
' .Cells.Clear
' .Range("A1").Resize(nr, nc) = contentOut
' End With
'Figure out size of calling range which will receive the output array
Dim nRow As Long: nRow = Application.Caller.Rows.Count
Dim nCol As Long: nCol = Application.Caller.Columns.Count
'Error if calling range too small
If nRow < UBound(contentOut, 1) Or nCol < UBound(contentOut, 2) Then
'Popup message
'MsgBox "your range is too small."
' or return #VALUE! error
SQL = "Too small range" 'CVErr(xlValue)
' or both or whatever else you want there to happen
Exit Function
End If
'Initialise output array to match size of calling range
Dim varOut As Variant
ReDim varOut(1 To nRow, 1 To nCol)
'And fill it with some background value
Dim iRow As Long
Dim iCol As Long
For iRow = 1 To nRow
For iCol = 1 To nCol
varOut(iRow, iCol) = "" ' or "funny bear", or whatever
Next
Next
'Put content in output array and return
For iRow = 0 To UBound(contentOut, 1)
For iCol = 0 To UBound(contentOut, 2)
varOut(iRow + 1, iCol + 1) = contentOut(iRow, iCol)
Next
Next
SQL = varOut
'Cleanup
Erase contentOut
Erase varHdr
Erase varDat
rs.Close
Set rs = Nothing
Set cn = Nothing
End Function
It looks like you are not specifying the fields/columns in the join. Both currAddress and curAddress2 look like tables. The SQL should be something like:
strSQL = "SELECT * FROM [Table1] " & _
"LEFT JOIN [Table2] ON [Table1].[Field] = [Table2].[Field];"
Are Indeks and Indeks2 your field names? If so, you need to place the field name after the table name:
strSQL = "SELECT * FROM [" & currAddress & "] " & _
"LEFT JOIN [" & currAddress2 & "] ON [" & currAddress & "].[Indeks] = [" & currAddress2 & "].[Indeks2];"
I believe 'Indeks' is your common field in the two tables, then strSQL should be this:
strSQL = "SELECT * FROM [" & currAddress & "] " & _
"LEFT JOIN [" & currAddress2 & "] ON [" & currAddress & "].[Indeks] = [" & currAddress2 & "].[Indeks]"

Extract employees between 2 Hire Dates VBA and SQL

I have designed a macro which should extract from a workbook database all employees who were hired between 2 Dates.
Unfortunatley I'm getting a error mesage when I run the query.
Error:
Data Type mismatch in criteria expression.
I don't know how to fix the issue.
My regional settings:
Short date: dd.MM.yyyy
Long date: dddd, d.MMMM.yyyy
First day of week: Monday
Here the code:
Public Sub HIREDATE()
Application.ScreenUpdating = False
Dim cnStr As String
Dim rs As ADODB.Recordset
Dim query As String
Dim fileName As String
Dim pom1 As String
Dim x As String, w, e, blad As String, opis As String
Set w = Application.FileDialog(msoFileDialogFilePicker)
With w
.AllowMultiSelect = False
If .Show = -1 Then
fileName = w.SelectedItems(1)
Else
Exit Sub
End If
End With
cnStr = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & fileName & ";" & _
"Extended Properties=Excel 12.0"
On Error GoTo Anuluj
x = InputBox("Wprowadz dwie daty od do oddzielając je przecinkiem -- Przykład 01.01.2015,01.05.2015")
strg = ""
k = Split(x, ",")
e = Application.CountA(k)
For m = LBound(k) To UBound(k)
If e = 1 Then
strg = strg & " [DEU1$].[Last Start Date] = '" & k(m) & "';"
Exit For
ElseIf e = 2 And e Mod 2 = 0 Then
strg = " [DEU1$].[Last Start Date] BETWEEN '" & CDate(k(m)) & "' AND '" & CDate(k(m + 1)) & "';"
Exit For
End If
Next m
On Error GoTo opiszblad
Set rs = New ADODB.Recordset
query = "SELECT [Emplid], [First Name]+ ' ' +[Last Name] From [DEU1$] WHERE" & strg
rs.Open query, cnStr, adOpenUnspecified, adLockUnspecified
Cells.Clear
Dim cell As Range, i As Long
With Range("A3").CurrentRegion
.Select
For i = 0 To rs.Fields.Count - 1
.Cells(1, i + 1).Value = rs.Fields(i).Name
Next i
Range("A4").CopyFromRecordset rs
.Cells.Select
.EntireColumn.AutoFit
End With
rs.Close
Application.ScreenUpdating = True
Exit Sub
Anuluj:
Exit Sub
opiszblad:
e = Err.Number
blad = Err.Source
opis = Err.Description
opisbledu = MsgBox(e & " " & blad & " " & opis, vbInformation, "Błąd")
Exit Sub
End Sub
You need properly formatted string expressions for your dates and to validate the user input:
If e = 1 And IsDate(k(m)) Then
strg = strg & " [DEU1$].[Last Start Date] = #" & Format(DateValue(k(m)), "yyyy\/mm\/dd") & "#;"
Exit For
ElseIf e = 2 And e Mod 2 = 0 And IsDate(k(m + 1)) Then
strg = " [DEU1$].[Last Start Date] BETWEEN #" & Format(DateValue(k(m)), "yyyy\/mm\/dd") & "# AND #" & Format(DateValue(k(m + 1)), "yyyy\/mm\/dd") & "#;"
Exit For
End If