Can't find msgbox code (Deleted it) but msgbox still appears - ms-access

I haven't even been able to find anyone with this problem online, let alone a solution!
I had several msgboxes in some VBA code I was writing to provide feedback for debugging. After a while the code was stable and I commented out the MsgBox lines.
One set of msgboxes wouldn't vanish though. I even deleted it rather than removing it. In the end I decided I must have a duplication somewhere, somehow, even though all the related code ended up calling this specific function where I'd removed the MsgBox.
I couldn't see any other explanation as I'd literally deleted the lines of code. I searched the entire project for fragments of the string which formed part of the MsgBox's text. Ctrl + F, set to search entire project, tried with and without pattern matching.
I found literally nothing. I decided the string must be more constructed than I thought, and instead opted to search using 'MsgBox' to search through every time I had used the command. I checked every single MsgBox in every project file and found nothing even remotely like the debugging message the code was still generating.
Anyone have any other ideas what may be going on? My best theory is that I've somehow hidden or duplicated something, but aside from depreciating a form whose code doesn't contain a single MsgBox or call code which does, I've done nothing I can think of to cause this.
I'd paste the code but you'd still just be taking my word for it that the MsgBox isn't there.
Can anyone help? It has to be hiding in there somewhere, somehow.
Many thanks,
Code where the MsgBox originally appeared (it provided feedback based on the RecordSet's NoMatch property):
Public Function createRecordSnapshot(Table As String, dbRefIn As String, payNum As String)
Dim fieldNames As String
Dim oldDataSet As String
Dim rs As Recordset
Dim fieldCount As Integer
Dim recordTot As Integer
Dim srchString As String
Set rs = CurrentDb.OpenRecordset(Table, dbOpenDynaset)
srchString = "DBRef = '" & dbRefIn & "' and PayrollRef = '" & payNum & "'"
fieldCount = rs.Fields.Count
rs.FindFirst (srchString)
Dim o As Integer
For o = 0 To fieldCount - 1
fieldNames = fieldNames & rs.Fields(o).Name & "|"
Next o
For o = 0 To fieldCount - 1
oldDataSet = oldDataSet & rs.Fields(o).Value & "|"
Next o
createRecordSnapshot = fieldNames & vbNewLine & oldDataSet
End Function

After a modification it is good practice to re-compile the code manually, as it makes running the code faster (can skip the compilation on next run) and refreshes previously compiled code. The option is in the VB Editor's Debug menu.

Related

VB.NET 2013: Change label text

I've been teaching myself VB.NET for a couple of weeks now, and I'm stumped. I have 18+ years experience in PHP, and so far the logic has been very similar. What I can't figure out is how to dynamically specify a label to change the text. What I have is 50 labels, one for each state. Then I have a MySQL query pulling a count for that state and then updating the label for the state.
My code currently is:
While dataReader.Read
If dataReader.Item("state") = "CO" Then
lblCO.Text = "(" & dataReader.Item("total") & ")"
lblCO.Visible = True
End If
End While
What I don't want to do is make 50 "IF" statements to specify the new text for each label. Each of the labels start with lbl and end with the two state abbreviation. For example: lblCA, lblCO, lblFL.
I thought I could concatenate like this: (similar style of concatenating in PHP)
While dataReader.Read
lbl&dataReader.Item("state").Text = "(" & dataReader.Item("total") & ")"
lbl&dataReader.Item("state").Visible = True
End While
I quickly found out that you can't concatenate like this in VB.NET.
Does anyone know how to do this dynamically? Or am I stuck making 50 "IF" statements?
Thank you!
I first want to thank Plutonix and Mike_OBrien. I was able to combine both of your responses to make a solution that worked perfect for me.
Plutonix: I figured out you had the ".Text" in the wrong place, but overall your snippet worked. Oh, in VB.NET 2013, it forced me to use "Me." instead of the form name.
Mike_OBrien: I liked your "IsNot Nothing" check
The solution that worked perfect for me:
While dataReader.Read
If Me.Controls("lbl" & dataReader.Item("state")) IsNot Nothing Then
Me.Controls("lbl" & dataReader.Item("state")).Text = "(" & dataReader.Item("total") & ")"
Me.Controls("lbl" & dataReader.Item("state")).Visible = True
End If
End While
So the above will make sure that the label exists. If it does exist, then it will update the text to the count that was pulled from MySQL. Like I said before, I'm very new to VB.NET. So even though the code above works, if anyone knows a reason that what I figured out might be bad for the application or system, I'm open for suggestions.
As long as you are in the code behind of the form you are trying to manipulate you could do:
Dim currControl = From r In Me.Controls Where DirectCast(r, Control).Name = "lbl" & StateAbbreviation Select r
You only need the DirectCast portion if you have option strict on otherwise you can do:
Dim currControl = From r As Control In Me.Controls Where r.Name = "lbl" & StateAbbreviation Select r
replace StateAbbreviation with whichever state you are currently trying to edit.
then do:
If currControl IsNot Nothing AndAlso currControl.Any Then
currControl(0).Text = "Whatever you want to assign to the label"
End If
This requires .NET 3.5 or greater. But it basically just uses LINQ to find the control you want to edit and then uses the reference to that control to set the display value.

How to get an AfterUpdate procedure to update other fields in the same form

As of Wednesday morning ...
First, I successfully display and select from my city_table, populating the city_no on the form
I am then attempting to use that value to extract/use the city_nm and state_nm on the same form.
I coded this as the (modified) afterupdate code for city_no.
Private Sub city_no_AfterUpdate()
Dim got_city_nm, got_state_nm
got_city_nm = DLookup("[city_nm]", "city_table", "[city_no]" = "city_no")
got_city_nm = DLookup("city_nm", "city_table", "city_no='" & Me.city_no & "'")
city_nm = got_city_nm
got_state_nm = DLookup("[state_nm]", "city_table", "[city_no]" = "city_no")
got_state_nm = DLookup("state_nm", "city_table", "city_no='" & Me.city_no & "'")
state_nm = got_state_nm
seat_no = "XXX"
End Sub
Still nothing happens including the last statement (assigning "XXX" to seat_no)
So I simplified it to just try that by itself:
Private Sub city_no_AfterUpdate()
seat_no = "XXX"
End Sub
Still nothing. I'm clearly missing something simple and trivial. I appreciate all the help. I've been working on this in my spare time as a personal project, using Access/VBA for the first time. I have about 4 hours into this project trying to learn it from public sources.
Open the VBA window and click in the left margin of the code. It will put a red dot in the margin. This is called a "break point". Run your form and make your change, and the code will stop where the break point is and highlight that line in yellow. To continue running through the code, press F8. This will run the lines of code one at a time and allow you to see exactly what's being processed.
When you get to each line of code, "hover" your mouse over the variables from the current and previous lines to see what the application THINKS the variable is equal to. You may find that what you think and what the app thinks are two different things at times.
If the code jumps over a bunch of lines and goes straight to the End Sub, you've got an error on the last line it highlighted.
Using this methodology is PARAMOUNT to understanding how VBA works. I've been working with it for 20 years and I still do this when I can't figure out what's wrong. See if this helps you answer your own question. If not, hopefully it will at least pinpoint a line of code that's not working properly and you can come back and ask a specific question about it.
EDIT: A quick look at the code makes me wonder something; is City_No a NUMBER or a TEXT? Because if it's a NUMBER, you want to get rid of the single quote around the variable. Text needs single quotes, numbers don't.
FURTHER EDIT: I think you need something more like this:
Private Sub city_no_AfterUpdate()
Dim got_city_nm, got_state_nm
got_city_nm = DLookup("city_nm", "city_table", "city_no='" & Me.city_no & "'")
Me.city_nm.Value = got_city_nm
got_state_nm = DLookup("state_nm", "city_table", "city_no='" & Me.city_no & "'")
Me.state_nm.Value = got_state_nm
seat_no = "XXX"
End Sub
If you're trying to fill in the value of a control (i.e. textbox), you need to reference it with "Me." (if it's on the same form) or "Forms!MyFormName." (if it's on another form).

Wrong RecordCount on Filtered Form with SQL View DataSource

I am using an Access2010 project as frontend, referring to a MS SQL Server 2008 as backend. Within my Access project there is form frmKlientenÜbersicht. This form has a view abfKlientenÜbersicht as dataSource.
Now I am trying to get the current number of records showing up in my form by using this code:
Private Sub Form_Current()
Debug.Print "Form_Current: " & anzahlDatensätze
lblAnzahlDatensätze.Caption = anzahlDatensätze & " Klient(en)"
End Sub
Private Function anzahlDatensätze() As Integer
Dim rs As Recordset
Set rs = Me.RecordsetClone
rs.MoveLast
anzahlDatensätze = rs.RecordCount
End Function
This works fine until I am using some filters. If I am using any filter on my form, the number of records stays unchanged!
What do I have to change to get the current number of records showing up (if filtered or not)?
What is the reason why my code does not show the correct number of records?
EDIT: According to the given comments and answers I tried setting Count([pkKlient] onto a textbox (see new pic) and tried DCount("*", "abfKlientenÜbersicht", me.Filter) from within VBA Code.
Unfortunatelly it seems that the filterClause is not valid when using it as parameter value for DCount. (see pic for filterClause).
As you can see count(..) does not result in a correct number - and the filterClause (generated by access!!) seems not to be valid for use by DCount(..)
If someone wants to try it, on your own, just create an ADP, add a form, add a view, form dataSource is a view, set a filter, and try to get the number of records?!!
Looking forward for any comments/answers/hints!
with VBA, DCount will give you what you need
DCount("*", "MyTable", Me.Filter)
If you want to put this on the form, there's an easier way. use an unbound box, and set it to =count([FieldName])
This count should remain correct, regardless of if it's counted filtered records or not.
Some notes, there are a dozen things that could go wrong with this, it could hardly even be called tested. However, it was returning the correct count for me.
Apparently, the form filter just hides records, whereas this will apply a real filter. However, you need to get the format into the right shape for a valid filter. In the end, a WHERE statement would probably be easier.
Private Sub Form_ApplyFilter(Cancel As Integer, ApplyType As Integer)
With Me.Recordset
''Filter
If ApplyType = 1 Then
''Very, very roughly. Remove form name, use single quotes
''You will need a lot more code for safety
sfilter = Replace(Me.Filter, "[" & Me.Name & "].", "")
sfilter = Replace(sfilter, """", "'")
.Filter = sfilter
MsgBox "Recordset : " & Me.Recordset.RecordCount & vbCrLf _
& "Filtered : " & .RecordCount
Else
''Remove filter - ApplyType 0
.Filter = ""
End If
End With
End Sub
Additional note with similar caveats
You can also set a textbox to something on these lines:
=IIf([FilterOn]=True,DCount("id","ATable",
Replace(Replace([Filter],"[" & [Name] & "].",""),"""","'")),Count([id]))
(Remove the break in the line, it is cosmetic)

VBA Executing CODE from a ComboBox

I have a very complex process that involves downloading a number of files from different shares, concatenating those files into working tables, manipulating and calculating related information, and then exporting specific fields (and calculations) as reports into a number of Excel workbooks.
I have this process coded so that I can click one button and the entire process will execute end to end. I have a series of text boxes that function as 'indicators' (red - this part failed, green - this part succeeded). As you can imagine, the code for the entire process is HUGE (32 pages when copied into MSWord) and difficult to weed through when I have a problem.
I got it into my mind that I wanted to put the code into a table so that it was much more modular and easier to deal with. I have setup a combo box with the action that I want to take and a second combo box with the report/file/object that I want to work with (ie Delete - Table 2, Acquire - File 1, Export - Report 4). I have been successful at creating the SQL statement to do simple things like del * from tbl_test and execute that from the combo boxes without any issue.
What I need to know is if there is a way to put what is essentially a code snippet into the table (memo field) and then have that vba code execute when I select the matching combos.
IE the code for 'Acquire - File1' is completely VBA code; it maps a network drive, locates the file, downloads the file, and moves it to a directory.
IE the code for 'Scrub - tblMain_Part1' is a combination of vba and sql code; it checks for the existence of a file (vba), if it finds it, it deletes a portion of the main table (sql) and appends the contents of the file it finds (sql), then it updates the monitor to indicate that it is completed (vba). If the file is not found, it changes the monitor box to red and updates a command button caption (vba)
I am NOT a genius with vba, but I hold my own. The thought process I had was that if I can essentially get the code broken into managable chunks in the table, I could call the code smippets in order if I want to run the entire process, or I could just re-execute portions of the code as needed by selecting the action and report/file/object combination.
Any thoughts/ideas are appreciated.
I think it would be best to split the code into Subs. The table you loop through would have a Sub-Name field and a blnSuccess field. Your code would loop though the table running each sub and then updating blnSuccess based on any errors you receive. This would give you queryable result set when you try to see what happened.
Consider using macros. You shouldn't need a table. Also, consider moving your hard-coded SQL to queries.
I think that you shouldn't use a table, just create a module with different subs for each operation. On your button event, after the combo selections, I would do a case statement.
dim strOperation as string
strOperation = me!selectionOne
Select Case strOperation
Case "delete": deleteTable(me!selectionTwo)
Case "export": export(me!selectionTwo)
case "acquire": acquire(me!selectionTwo)
End Select
Of course, you'd have your acquire, delete, and export methods written in a module and have whatever parameters you need for each operation there.
This is just one idea of many that you could use to approach this.
I was going to edit the original answer but this seems to be off on a different tack....
I think it would be best to split the code into functions that return a string if there is an error. The table you loop through would have a strFunction,strError and strObject fields. Your code would loop though the table running each function based on the case statement while passing the strObject as a string and then updating strError based on any errors you receive. You could query the table after this process to see which records have errors in them.
If the button is called cmdRunAll here is the code for it.
Private Sub cmdRunAll_Click()
On Error GoTo ErrHandler
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("tblCode", dbOpenDynaset, dbSeeChanges)
If Not rst.EOF Then
With rst
.MoveFirst
Do While Not .EOF
.Edit
Select Case !strFunction
Case "fExport"
!strError = fExport(!strObject)
End Select
.Update
.MoveNext
Loop
End With
End If
rst.Close
Set rst = Nothing
MsgBox "Processes complete"
Exit Sub
ErrHandler:
Debug.Print Err.Description & " cmdRunAll_Click " & Me.Name
Resume Next
End Sub
Here is a simple sample function
Public Function fExport(strTable As String) As String
On Error GoTo ErrHandler
Dim strError As String
strError = ""
DoCmd.TransferText acExportDelim, , strTable, "C:\users\IusedMyUserNameHere\" & strTable & ".txt"
fExport = strError
Exit Function
ErrHandler:
strError = Err.Description
Resume Next
End Function

user defined Parameter used as part of a filename in Access

I have an access 2007 Database that outputs a report in excel format, the report is dependent on a date parameter that is chosen by the user. This parameter is selected via a textbox (text100) that has a pop up calendar. I would like to use the date in the text box(text100) as part of the filename. I am using the transferspreadsheet method to create the export, However I do not need the column headers. Once the file is created I have the code open the file and delete the headers. Also the current code is using todays date in the filename which is not accurate. The filename needs to reflect the date that was selected by the user in the text box from the pop up calendar
Ok here is the code.
Sub Branch298nohdr()
Dim Filename As String
Dim Path As String
Dim Branch As Integer
Dim Text100 As Date
Dim xl
Branch = "298"
Path = "Path" & Branch & "\"
Filename = "Identity Report " & Branch & " " & _
Replace(Text100, ":", " ") & ".xls"
If Dir(Path & Filename) <> "" Then
MsgBox "File has been created already"
If Dir(Path & Filename) <> "" Then
GoTo 53
End If
Else
Set xl = CreateObject("excel.application")
TempVars.Add "branchnum", Branch
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel8, _
"queryname", Path & Filename, False
xl.workbooks.Open Path & Filename
With xl
.Rows("1:1").entirerow.Delete
.Columns("L:L").select
.Selection.NumberFormat = "0"
.range("a1").select
xl.workbooks(1).Close Savechanges:=True
xl.Quit
Set xl = Nothing
53
MsgBox "Done!"
End With
TempVars.Remove "branchnum"
End If
Branch298nohdr_Exit:
Exit Sub
End Sub
Text 100 is where the user selects a date via a pop up calendar. I would like to use this date as part of the file name. Currently using the text100 as part of the filename it is being referenced as 12:00 am, and then adds this to the file name. I hope this clears up my intention.
Text 100 gets set on the opening form then there are several buttons which allow the user to pick between several branches or all branches.
Well the obvious question is, where does Text100 get first set?
Another style comment, it is better to do
goto ExitSub
'...
ExitSub:
Then your "GoTo 53" - its a little more meaningful.
At that rate, it would be better to move your "Done" message outside of the IF statements, and the TempVars doesn't seem to have a purpose; remove it.
Edit:
I presume if Text100 is a textbox on the form, then the line that reads:
Dim Text100 As Date
is going to override that reference in your code.
If you are referencing that textbox in your code, you need to do it this way:
foo = me.Text100
' or
foo = Forms!FormName.Text100
It's a little tough to determine exactly what your question is, but I think you are asking, "how do I use the contents of a text box as an export file name?" It sounds like somewhere in your code it creates a string for the filename that has & now() tagged on to the end to use the current date in the filename. Can you simply replace the '& now()' with '& textbox.value'?
A JD Long said it is hard to see any question in your posting. Maybe you should edit it again.
But as a general remark you need to escape any special characters that the user entered before you are going to use the input in a file name.
The following reserved characters are not allowed:
< > : " / \ | ? *
For more details on naming files in Windows see: Naming a File or Directory in MSDN.