Access Combobox returns wrong values after query - vba

I have the problem, that the Combobox returns strange values after I click a button, which performs a query on that form.
The rowsource is assigned in VBA and I have checked that the value of ST_Id always stays the same
Here is the VBA code:
Private Sub Form_Load()
dYear = Year(Now)
dMonth = Month(Now)
getDate = DateSerial(dYear, dMonth + 1, 0) 'to get the last day of this month
ST_Id = DLookup("[ID]", "ReportingDays", "[ReportingDay] =#" & Format(getDate, "yyyy\/mm\/dd") & "#") 'returns the ID that is saved in ReportingDays-table
Forms!frm_Team!ReportingMonth.RowSource = "SELECT ReportingDays.ID, ReportingDays.MonthText FROM ReportingDays " _
& " WHERE ReportingDays.ID > " & ST_Id - 3 & " AND ReportingDays.ID < " & ST_Id + 10 & ";" 'fills Combobox with values -2 and + 9 months from the actual month
End Sub
When I open the form the first time everything works fine:
But after the form performs a query the combobox values get messed up like this:
Requerying the Combobox in VBA did not change anything.
I hope you can help me with this issue, because I have not been able to solve this for days.
Kind regards
Nick Thomas

This can be done much simpler:
Private Sub Form_Load()
Const RowSource As String = _
"Select ID, MonthText From ReportingDays " & _
"Where DateDiff('m', Date(), ReportingDay) Between -2 And 10"
Me!ReportingMonth.RowSource = RowSource
End Sub

Related

in a form access 2019 why listbox liststyle doesn't work

I want to create a listbox in a form, with multiple selection and checkbox. The liststyle property is not found and the instructions of the web pages do not work :
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/liststyle-property
https://learn.microsoft.com/en-us/office/vba/api/outlook.listbox
it is unclear exactly what you are trying to do but format the checkbox and listbox to look like the same control. Then hook them up with vba behind the scenes. I found some of my really old code where I had a non standard data entry form and a bunch of checkboxes. at the time I added a button and hooked everything up in the button click event.
Private Sub cmdSaveLog_Click()
SaveLogEntry cmbHour1, cmbMinutes1, txtNotes1, chkAsleep1, chkSaveEntry1
SaveLogEntry cmbHour2, cmbMinutes2, txtNotes2, chkAsleep2, chkSaveEntry2
SaveLogEntry cmbHour3, cmbMinutes3, txtNotes3, chkAsleep3, chkSaveEntry3
SaveLogEntry cmbHour4, cmbMinutes4, txtNotes4, chkAsleep4, chkSaveEntry4
SaveLogEntry cmbHour5, cmbMinutes5, txtNotes5, chkAsleep5, chkSaveEntry5
SaveLogEntry cmbHour6, cmbMinutes6, txtNotes6, chkAsleep6, chkSaveEntry6
SaveLogEntry cmbHour7, cmbMinutes7, txtNotes7, chkAsleep7, chkSaveEntry7
SaveLogEntry cmbHour8, cmbMinutes8, txtNotes8, chkAsleep8, chkSaveEntry8
SaveLogEntry cmbHour9, cmbMinutes9, txtNotes9, chkAsleep9, chkSaveEntry9
SetFilter
End Sub
Private Sub SaveLogEntry(cmbHours As ComboBox, cmbMinutes As ComboBox, txtNotes As textbox, chkAsleep As CheckBox, chksave As CheckBox)
'note logtime is inserted as a double, txtdetails needs to be quoted in string
'If Trim(cmbHours.value & vbNullString) = vbNullString Then 'textbox empty
If chksave.value = True Then
Dim DailyID As Long
Dim item As Variant
Dim logtime As Double 'insert and dates don't mix
'Dim currentboy As Long
'logtime = CDbl(CDate(cmbDate.value)) + (txtHour.value + txtMinute.value / 60) / 24 'how to convert date, hour, minute to date with time
'logtime = Int(cmbDate.value) + cmbHours.value + cmbMinutes.value
' loop list box
'DailyID = GetDailyID(CLng(lstBoys.Column(0, item)), CDate(cmbDate.value))
DoCmd.SetWarnings False
For Each item In lstBoys.ItemsSelected
DailyID = GetDailyID(CLng(lstBoys.ItemData(item)), CDate(cmbDate.value)) 'group by date at start of shift
If cmbHours.value + cmbMinutes.value > 0.5 Then 'before midnight
'DailyID = GetDailyID(CLng(lstBoys.ItemData(item)), CDate(Int(cmbDate.value)))
'DailyID = GetDailyID(CLng(lstBoys.ItemData(item)), CDate(cmbDate.value))
logtime = CDate(cmbDate.value) + cmbHours.value + cmbMinutes.value
Else
'DailyID = GetDailyID(CLng(lstBoys.ItemData(item)), CDate(Int(DateAdd("d", 1, cmbDate.value))))
'DailyID = GetDailyID(CLng(lstBoys.Column(0, item)), CDate(Int(DateAdd("d", 1, cmbDate.value))))
logtime = DateAdd("d", 1, cmbDate.value) + cmbHours.value + cmbMinutes.value
End If
'DailyID = GetDailyID(CLng(lstBoys.ItemData(item)), CDate(Int(cmbDate.value))) ' for some reason date had a time stamp so int to truncate time
'DailyID = GetCorrectDailyID(CLng(lstBoys.ItemData(item)), CDate(Int(cmbDate.value)), cmbHours.value + cmbMinutes.value) ' for some reason date had a time stamp so int to truncate time
If IsNull(txtNotes) Or txtNotes = "" Then
DoCmd.RunSQL ("INSERT INTO NightLogs ( DailyID, InspectionTime, Asleep, StaffID) " & _
"SELECT " & DailyID & ", " & logtime & ", " & chkAsleep.value & ", " & cmbStaff.value)
Else
DoCmd.RunSQL ("INSERT INTO NightLogs ( DailyID, InspectionTime, Asleep, Details, StaffID ) " & _
"SELECT " & DailyID & ", " & logtime & ", " & chkAsleep.value & ", """ & txtNotes & """" & ", " & cmbStaff.value)
End If
Next item
DoCmd.SetWarnings True
Else
'do nothing
End If
End Sub
Depending on what you want to do you may also be able to use the checkbox click event rather than a button. The point is let the Access controls do the visual stuff they are good at and use VBA to refer to the controls like settings and finish the job.

Using a form control as a field selector in SQL query

I am attempting to build a form ,called UI, that users will select a dimension parameter from a combobox "cmbFilter" and then add a +/- tolerance in a text box "txtTolerance". After selection a part number from a list this should return results for similar part numbers in the the tolorence range for that parameter. The field names in the table are the dimension parameters and are .AddItem to the combobox in the form load code.
Example. Part#1 OD is 5, so I select "OD" as the search parameter then I set a tolerance to +/- 1. The results should show Part#2 with a OD of 6 but not Part#3 with a OD of 7.
I have set a listboxs row source to the query but
no matter what I change in the syntax in this code I get operation or syntax errors. So I assume Im not referencing the form control right, or my logic isn't right?
I have tired the following code in the SQL design view in access.
SQL
SELECT Part_Matrix.Part_Number, Part_Matrix.Customer, Part_Matrix.Large_OD, Part_Matrix.Vent_Opening, & _
Part_Matrix.BPT, Part_Matrix.MFT, Part_Matrix.PD, Part_Matrix.Hat_ID, Part_Matrix.Microfinish, & _
Part_Matrix.Turn_Operations, Part_Matrix.Stud_Holes, Part_Matrix.SH_Dimensions, Part_Matrix.Manufacturer_Holes, & _
Part_Matrix.MH_Dimensions, Part_Matrix.Other_Holes, Part_Matrix.Other_Dimension
FROM Part_Matrix
WHERE [Forms]![UI]![cmbFilter]
BETWEEN (((SELECT [Forms]![UI]![cmbFilter] FROM Part_Matrix WHERE Part_Number = [Forms]![UI]![lbSelected]) - [Forms]![UI]![txtTolerance])
AND ((SELECT [Forms]![UI]![cmbFilter] FROM Part_Matrix WHERE Part_Number = [Forms]![UI]![lbSelected]) + [Forms]![UI]![txtTolerance]))
ORDER BY [Forms]![UI]![cmbFilter] DESC;
I have also tried to write the SQL code in access vba still no luck, the code below was just a simple text, I know its now the same logic as above.
Private Sub btnSearch_Click()
Dim SQL As String
If txtTolerance = "" Then
MsgBox ("No Tolerance Entered")
Exit Sub
ElseIf cmbFilter = "" Then
MsgBox ("No Filter Criteria Entered")
Exit Sub
Else
SQL = "SELECT Part_Matrix.[Part_Number], " & Me.cmbFilter & " " & _
"FROM Part_Matrix" & _
"ORDER BY " & Me.cmbFilter & " DESC;"
Debug.Print SQL
DoCmd.RunSQL SQL
lbFilterResults.RowSource = SQL
lbFilterResults.Requery
End If
End Sub
Try this, using a dlookup instead of SELECT to return the values you want in the BETWEEN statement. I believe the dlookup should return the value for whatever field you select in the combo box. Also, I've simplified to remove the forms!UI statement with a "me" assuming you are running code from the same form. Let me know if this works for ya.
intTarget = dlookup(me!CmbFilter, "PartMatrix", "Part_Number = " & me!LbSelected)
intLower = intTarget - me!txtTolerance
intUpper = intTarget + me!txtTolerance
strSQL = "SELECT * FROM Part_Matrix WHERE " & me!cmbFilter & " " & _
"BETWEEN " & intLower & " AND " & intUpper
In your BETWEEN statement, reference the table's [Large_OD] field and not the form'S.
i.e
WHERE Large_OD
BETWEEN (((SELECT Large_OD FROM Part_Matrix WHERE Part_Number = [Forms]![UI]![lbSelected]) - [Forms]![UI]![txtTolerance])
AND ((SELECT Large_OD FROM Part_Matrix WHERE Part_Number = [Forms]![UI]![lbSelected]) + [Forms]![UI]![txtTolerance]))
ORDER BY " & Me.cmbFilter & " DESC;

VBA ACCESS Comparing String as they are integer

I am trying to prompt the user to input a range and display all the instruments that are within that range in a subform.
Problem: The upper and lower range is a text field (because some of the range cannot be expressed in integer). As seen in the screenshot, the comparison only compare the first character of the field.
User's input: 5 - 3
On the subform: 36 - 4
It compares 5 and 3 instead of 36
I know vba is doing what it has been told but how can I achieve the result I want?
Here is my code for requering the subform:
Dim Up As Integer
Dim Low As Integer
If Me.Text_L = "" Or IsNull(Me.Text_L) Or Me.Text_U = "" Or IsNull(Me.Text_U) Then
MsgBox ("Please choose a valid range!")
Else
Up = Me.Text_U
Low = Me.Text_L
SQL = SQL_Origin & " WHERE [qry_View_Search].[Upper_Range] <= '" & Up & "' " _
& "AND [qry_View_Search].[Lower_Range] >= '" & Low & "';"
subform_View_Search.Form.RecordSource = SQL
subform_View_Search.Form.Requery
End If
so what i did is made a new column in the query for
IIf(IsNumeric([Upper]), Val([Upper]), Null)
to get all the numeric result.
Then in the vba, I re query the subform as below
SQL = SQL_Origin & " WHERE [qry_View_Search].[Upper] <= cint(Forms![frm_View_Search]![Text_U]) " _
& "AND [qry_View_Search].[Lower] >= cint(Forms![frm_View_Search]![Text_L]);"
Thanks #HansUp !
I have successfully for those cases used Val only:
Value: Val([FieldName])
or:
Value: Val(Nz([FieldName]))

ACCESS 2007 - Form / subform filtering between dates

In ACCESS 2007 I have a main form with two unbound comboboxes named cmbStavOd and cmbStavK, both formatted as Short Date.
I have a subform named frm_qryNaklady_subform, based on a query with a field named datNakladDatum (textbox name datNakladDatum), formatted as Short Date.
I'd like to allow users to enter a date range and have the subform filtered to only show records of the date range entered in the main form boxes.
I'm using a VBA code in AfterUpdate event like:
Dim datRokMesiacOd As Date
Dim datRokMesiacDo As Date
Dim strFilterNaklady As String
datRokMesiacOd = DateSerial(Year(cmbStavOd), Month(cmbStavOd), 1) 'begin Date
datRokMesiacDo = DateSerial(Year(cmbStavK), Month(cmbStavK) + 1, 1) - 1 'end Date
strFilterNaklady = "[datNakladDatum] Between #" & datRokMesiacOd & "# And #" & datRokMesiacDo & "#"
With Me.frm_qryNaklady_subform.Form
.Filter = strFilterNaklady
.FilterOn = True
End With
For instance, result for strFilterNaklady looks like this: "[datNakladDatum] Between #1. 1. 2015# And #31. 12. 2015#".
By debugging the code I receive an error message at statement:
With Me.frm_qryNaklady_subform.Form
.Filter = strFilterNaklady
.FilterOn = True
End With
Error 3709 - The search key was not found in any record.
But the underlying query contains tons of records fitting entered date range.
I'm playing with date filtering syntax all the day, but without success.
Do you see where I'm going wrong?
You need proper date formatting:
strFilterNaklady = "[datNakladDatum] Between #" & Format(datRokMesiacOd, "yyyy\/mm\/dd") & "# And #" & Format(datRokMesiacDo, "yyyy\/mm\/dd") & "#"
Also, this can be reduced to:
datRokMesiacDo = DateSerial(Year(cmbStavK), Month(cmbStavK) + 1, 0) 'end Date

How to run query, automate using VBA Macro and Excel, make "loading" feature while reconciling?

I am building a reconciliation tool via VBA that automates queries from my oracle database and a worksheet. When I run the query I want the user to input what ITEM (in this case pipeline) to query (the worksheet has many items) and the end/start dates. I am having trouble figuring out the following:
1) It is querying - if the value is NULL, how may I tell it to print out "DATA NOT AVAILABLE"
2) How can I clear up the old output from pipeline A, when I am querying pipeline B?
3) My dates are saved as strings in Oracle - how can I convert that to date?
Thank you!
Here is what I have so far:
Option Explicit
Option Base 1
Dim cnnObject As ADODB.Connection
Dim rsObject As ADODB.Recordset
Dim strGPOTSConnectionString As String
Dim startDate As Date
Dim endDate As Date
Dim strPipelineName As String
Dim strQuery As String
Sub ClickButton2()
Debug.Print ("Button has been clicked")
Dim Pipeline As String
Dim DateStart As Date
Dim DateEnd As Date
Pipeline = InputBox("Enter PipeLine", "My Application", "Default Value")
DateStart = InputBox("Enter Start Date", "My Application", DateTime.Date)
DateEnd = InputBox("Enter End Date", "My Application", DateTime.Date + 1)
Pipeline = Range("B1").Value
DateStart = Range("B2").Value
DateEnd = Range("B3").Value
strQuery = "select pipelineflow.lciid lciid, ldate, volume, capacity, status, " & _
"pipeline, station, stationname, drn, state, county, owneroperator, companycode, " & _
"pointcode, pottypeind, flowdirection, pointname, facilitytype, pointlocator, " & _
"pidgridcode from pipelineflow, pipelineproperties " & _
"where pipelineflow.lciid = piplineproperties.lciid " & _
"and pipelineflow.audit_active = 1 " & _
"and pipelineproperties.audit_active =1 " & _
"and pipelineflow.ldate >= '" & Format(DateStart, "dd-MMM-yyyy") & "' and pipelineflow.ldate < '" & Format(DateEnd, "dd-MMM-yyyy") & "' " & _
"and pipelineflow.ldate >= '" & DateStart & "' and pipelineflow.ldate < '" & DateEnd & "' " & _
"and pipelineproperties.pipeline = '" & Pipeline & "' "
Call PullZaiNetData(strQuery)
Call TieOut
End Sub
Sub PullZaiNetData2(ByVal strQry As String)
Set cnnObject = New ADODB.Connection
Set rsObject = New ADODB.Recordset
strGPOTSConnectionString = "DRIVER={Microsoft ODBC for Oracle}; SERVER=hhh; PWD=hhhh; UID=hhh"
cnnObject.Open strGPOTSConnectionString
rsObject.Open strQry, cnnObject, adOpenStatic
Worksheets("ZaiNet Data").Cells(1, 1).CopyFromRecordset rsObject
rsObject.Close
cnnObject.Close
Set rsObject = Nothing
Set cnnObject = Nothing
End Sub
Sub TieOut()
End Sub
Since you changed your questions, I'll add another answer.
1) It is querying - if the value is NULL, how may I tell it to print out "DATA NOT AVAILABLE"
Which value? I suspect that you mean when the query returns no records. To check this, test for rsObject.RecordCount = 0:
Dim ws As Worksheet
Set ws = Worksheets("ZaiNet Data")
ws.UsedRange.Clear '' remove results of previous query if any
If rsObject.RecordCount = 0 Then
ws.Cells(1, 1) = "DATA NOT AVAILABLE"
Else
ws.Cells(1, 1).CopyFromRecordset rsObject
End If
You can also test for one or both of rsObject.BOF or rsObject.EOF being true ("Beginning Of File" or "End Of File" respectively).
When developing things in VBA, especially when using new features that I'm unfamiliar with, I do lots of tests that output things to the Immediate Window. To help with this, I use the following little routine:
Sub Say(s as String)
Debug.Print s
End Sub
It makes it a little easier to generate testing output that typing "Debug.Print" all the time (even slightly easier than typing "Debug.P" + Enter using Intellisense).
So when you open your recordset, show the record count after it:
rsObject.Open strQry, cnnObject, adOpenStatic
Say rsObject.RecordCount & " records"
Do something like this any time you want to verify a value.
Later on, if you want to capture your debugging statements in a text file, you just need to change the operation of the Say() routine.
2) How can I clear up the old output from pipeline A, when I am querying pipeline B?
As shown in context above:
ws.UsedRange.Clear '' remove results of previous query if any
3) My dates are saved as strings in Oracle - how can I convert that to date?
You don't technically need to convert the resulting date strings to date values, you may find that just by putting them in a cell, Excel will treat them as date values.
You just need to make sure that the user's dates get converted to the format that the database is expecting.
Your query string as it stands above still shows two lines incorporating the user's dates. The one that uses Format() to convert them to "dd-MMM-yyyy" format is the one you want to keep. Delete the other line, making sure your string concatenating syntax is still correct.
To actually convert the date string to a date value though, you would use the CDate() function:
Sub DateTest()
Dim sDate As String
Dim dDate As Date
sDate = "09-Jul-2009"
dDate = CDate(sDate)
Say "sDate = " & sDate
Say "dDate = " & dDate
dDate = dDate + 1
Say "dDate = " & dDate
End Sub
Immediate Window output:
sDate = 09-Jul-2009
dDate = 7/9/2009
dDate = 7/10/2009
We can verify that it converted the string to a date value because it shows up in the default date format for my machine, and responds to date math (adding 1 day).
Answers to previous questions (paraphrased):
1) "how to make sure end date is after start date":
Valid date values are floating point numbers, so DateEnd should be >= DateStart. The whole number part is the number of days since 1900-01-01. The fractional part is the current time of day (eg 12 noon = 0.5).
2) "use fancy calendar entry controls for dates"
Look at the controls available under the Insert> Object menu (in Excel 2003 and earlier - it's in 2007 too, but in a different place). One of them is a Calendar control. Double-clicking it in the Objects list will insert it into the current cell and put the sheet into Design Mode. Right click the control and choose Properties. Type a cell address into the LinkedCell field. Then click the "Exit Design Mode" button from the little toolbar that should have popped up. Now when you select a date on the control, it will show the value in the cell you linked it to.
Similarly there is a drop down list control that you can use to select your pipeline types.
3) "why am I getting an error on DateEnd = Range("B3").Value?"
The DateEnd error is probably due to a missing or invalid value in the cell you specified, as I asked in my comment.
What version of Excel are you doing this in? Excel 2003