Select Case & Try statement infinite loop - vb.net

When trying to print a report in my vb.net project, I have some code to check whether all of the required fields have been filled in. If it isn't, a message box appears to notify the user. When they press 'OK', I need the program to stop executing the code to load the report. At the moment, it is stuck in an infinite loop, where it goes through a Try function and a SELECT CASE repeatedly instead.
What needs changing to stop this? I can't work out what the issue is, and why the following sections of code keep looping round one after the other
Try
Select Case checkwhat.ToUpper
Case "SUPPLIER"
If cmbSuppliers.Text.Trim = "" Then
MsgBox("Please select a supplier", MsgBoxStyle.OkOnly, "No Supplier Selected")
Return False
Exit Try
End If
Case "RB6B"
check("SUPPLIER")
If check("SUPPLIER") = True Then Else Exit Sub
createWorkTable("SUPPLIERS-TERRITORY-LS")
regReport("rTerritoryWTableCrosstabB.rpt", "", con, Me.MdiParent, cReport, True)
fillPms(cReport, "Sales by Territory by Supplier", "For " & cmbSuppliers.Text.Trim, "", "AOT02")

This is not a full answer but I can at least address some issues:
Select Case checkwhat.ToUpper
Case "SUPPLIER"
If cmbSuppliers.Text.Trim = "" Then
MsgBox("Please select a supplier", MsgBoxStyle.OkOnly, "No Supplier Selected")
Return False
Exit Try '<- Redundant
Else
' Perform other checks
Return True
End If
So this means you can at least get both return values assuming you enter the supplier case.
Now.. In your RB6B case, you run the check function twice.
Case "RB6B"
check("SUPPLIER")
If check("SUPPLIER") = True Then
The two options you have are:
Dim supplierValid as Boolean = check("SUPPLIER")
If supplierValid = True
Or just removing the first line
If check("SUPPLIER") = True Then
Okay. So following that:
If check("SUPPLIER") = True Then Else Exit Sub
Try and avoid using this style, because it can hide code paths and you may miss some functionality without realising. Two options shown below. One avoids additional nesting
If check("SUPPLIER") = True Then
createWorkTable("SUPPLIERS-TERRITORY-LS")
regReport("rTerritoryWTableCrosstabB.rpt", "", con, Me.MdiParent, cReport, True)
fillPms(cReport, "Sales by Territory by Supplier", "For " & cmbSuppliers.Text.Trim, "", "AOT02")
Else
Exit Sub
End If
Or
If check("SUPPLIER") = False Then
Exit Sub
End If
createWorkTable("SUPPLIERS-TERRITORY-LS")
regReport("rTerritoryWTableCrosstabB.rpt", "", con, Me.MdiParent, cReport, True)
fillPms(cReport, "Sales by Territory by Supplier", "For " & cmbSuppliers.Text.Trim, "", "AOT02")

Related

MS Access: Why is my code not being reached?

Im trying to do some error handling for my code and I want my custom error message to appear if the user is trying to enter an already existing record. Access gives its own standard error message indicating a duplicate record, but I want mine displayed instead. The issue is the part of the code where I have my custom error message isn't being reached, therefore giving me the default message.
The name of the textbox is "DepartmentCode", the name of the table its being drawn from is "tDepartment" and the column name is "DepartmentCode"
My code is this...
Private Sub bAddDepartment_Click()
On Error GoTo bAddDepartment_Click_Err
Dim OKToSave As Boolean
OKToSave = True
If Not SomethingIn(Me.DepartmentCode) Then ' Null
Beep
MsgBox "A department code is required", vbOKOnly, "Missing Information"
OKToSave = False
Else
Dim myDepartmentCode As String
myDepartmentCode = "DepartmentCode = " + Chr(34) + Me.DepartmentCode + Chr(34)
If DLookup("DepartmentCode", "tDepartment", myDepartmentCode) <> Null Then
MsgBox "Department already on file", vbOKOnly, "Department already on file."
OKToSave = False
End If
End If
If OKToSave Then
' If we get this far, all data is valid and it's time to save
Me.Dirty = False
DoCmd.GoToRecord , "", acNewRec
End If
bAddDepartment_Click_Exit:
Exit Sub
bAddDepartment_Click_Err:
Resume bAddDepartment_Click_Exit
End Sub
The part not being reached is If DLookup("DepartmentCode", "tDepartment", myDepartmentCode) <> Null Then
Why is this happening?
Debugging VBA Code <-- to see which lines are actually executed.
If DLookup("DepartmentCode", "tDepartment", myDepartmentCode) <> Null Then
You can't compare to Null like that. Try this in the Immediate Window:
? ("foo" <> Null)
Null
Use IsNull()
If Not IsNull(DLookup("DepartmentCode", "tDepartment", myDepartmentCode)) Then
or if empty strings are also possible, use Nz()
If Nz(DLookup("DepartmentCode", "tDepartment", myDepartmentCode), "") <> "" Then

In Access form, is there a way to use a search box to populate the form using VBA?

I have two solutions I've been working to solve this problem...
Attempt #1
I have a combo box in an Access form with two options, "All," and "All Sample." The Sample is a selection of records from my table that are flagged for review with a sample_record_id (text field) for identification with a non-zero positive number. "All" and "All Sample" are in my Row Source. My combo box is named myFilters.
Afterupdate, this VBA runs:
Private Sub myFilters_AfterUpdate()
Debug.Print myFilters.Value
If myFilters.Value = "All Sample" Then
Me.FilterOn = True
DoCmd.ApplyFilter , "sample_record_id <> '0'"
Else
Me.FilterOn = False
End If
End Sub
All records have an entry for sample_record_id.
I was expecting my sample records to populate when "All Sample" is selected, and all records to populate otherwise. In fact, all records do populate when "All" is selected, but when "All Sample" is selected, a "Enter Paramaters Value" dialog box appears with the text "sample_record_id" with a space for entering text.
Interestingly, when I switch the IF and ELSE:
If myFilters.Value = "All" Then
Me.FilterOn = False
Else
Me.FilterOn = True
DoCmd.ApplyFilter , "sample_record_id <> '0'"
...neither selection works as expected.
Attempt #2
I also tried the following VBA:
Private Sub myFilters_AfterUpdate()
DoCmd.SetWarnings False
strSQL = "SELECT * FROM invoice_summary WHERE sample_record_id <> '0';"
Debug.Print strSQL
DoCmd.RunSQL strSQL
DoCmd.SetWarnings True
End Sub
I was expecting this to do the same thing as previous code, but no matter which selection I pick, a debug error pops up saying "A RunSQL action requires an argument consisting of a SQL statement."
Debug of strSQL returns: SELECT * FROM invoice_summary WHERE sample_record_id <> '0';
I've tried it with and without the ;
The sql statement works in a standard query.
Is there a way to make either of these work?
Been working on this for two days, and 30 minutes after I post I figure it out. Sigh.
Using my first attempt, I just had to put brackets around my field name:
Private Sub myFilters_AfterUpdate()
If myFilters.Value = "All Sample" Then
Me.FilterOn = True
DoCmd.ApplyFilter , "[sample_record_id] <> '0'"
Else
Me.FilterOn = False
End If
End Sub

Case Statement true and False?

I'm working on an AutoCAD VBA program that creates a drawing.
But i have a slight problem. If "Case 1" is True Then "Case 2" must be false. Here is my code :
Sub Pumps()
'Option for type of pump piping
ans = InputBox("1 = STD Piping" & vbCrLf & _
"2 = Omit Pump", "Pump Piping")
Select Case ans
Case "1":
: Set layerObj = ThisDrawing.Layers.Add("PUMP-PIPING STD -" & Size)
layerObj.LayerOn = True
Case "2":
: Set layerObj = ThisDrawing.Layers.Add("OMIT PUMP -" & Size)
layerObj.LayerOn = True
Case Else: MsgBox "Wrong Input Dude.", vbCritical, MSG: Exit Sub
End Select
End Sub
Please Assist
So I'm not sure what the end goal was, but hopefully this gets you started.
What I've done I've isolated the "decision making" to the switch block, and that sets the toggle variable which is needed for the "work" to be done later. (and I would consider moving that "work" of actually setting the layerObj out to another Sub
Sub Pumps()
Dim ans As String
'Option for type of pump piping
ans = InputBox("1 = STD Piping" & vbCrLf & _
"2 = Omit Pump", "Pump Piping")
Dim toggle As Boolean
Select Case ans
Case "1": toggle = True
Case "2": toggle = False
Case Else: MsgBox "Wrong Input Dude.", vbCritical, MSG: Exit Sub
End Select
Set layerObj = ThisDrawing.Layers.Add("PUMP-PIPING STD -" & Size)
layerObj.LayerOn = toggle
Set layerObj = ThisDrawing.Layers.Add("OMIT PUMP -" & Size)
layerObj.LayerOn = Not (toggle)
End Sub
Remove the : from your code all over. Every single one of them.
It makes plenty of problems, especially with Conditions. You really cannot follow what is happening.
In general, the : means that you want the next line to stay on the similar line. It is useful only when you want to assign values to a newly declared variable like this: Dim k as long: k = 5 and its idea is to save space.
Take a look at this topic, you would understand what I mean:
VBA - How the colon `:` works in VBA code with condition

How to close a form after opening another one on top of it

I have the following code - The purpose is that after saving an order, it is has been set to cancelled, then I want it to show the "New Order" form - This works fine!
However, once the new form has been opened, I want the original form, with the cancelled order, to be closed.
Try
cmdCheck_Click(sender, New EventArgs)
cmdTotals_Click(sender, New EventArgs)
For Each ugr As UltraGridRow In ugProducts.Rows
If IsDBNull(ugr.Cells("Commission_Value").Value) = True Then
MsgBox("Unable to save an order where one or more lines has a commission value of 0", MsgBoxStyle.OkOnly, "Error")
Exit Sub
Else
If ugr.Cells("Commission_Value").Value <= 0 Then
MsgBox("Unable to save an order where one or more lines has a commission value of 0", MsgBoxStyle.OkOnly, "Error")
Exit Sub
End If
End If
Next
If chCancel.Checked = True Then
If MsgBox("Are you sure you would like to cancel this order?", MsgBoxStyle.YesNo, "Confirm") = MsgBoxResult.No Then
Exit Sub
End If
End If
If cmbCustCode.Value = "" Or cmbSupplier.Value = "" Or txtOVal.Text = "" Or txtPVol.Text = "" Or txtPVal.Text = "" Then
MsgBox("Not enough required data has been entered, cannot save this order", MsgBoxStyle.OkCancel, "Error")
Exit Sub
End If
If isClear = True Then
Try
setNewValues()
Catch ex As Exception
errorLog(ex)
MsgBox("Unable to save data, refer to error log", MsgBoxStyle.OkOnly, "Error")
Exit Sub
End Try
End If
gOrder.Freight = CDec(txtFVal.Text)
gOrder.AmendedVal = CDec(txtOVal.Text)
gOrder.AmendedVol = CDec(txtPVol.Text)
gOrder.externalNotes = rtbExternalNotes.Text
gOrder.InternalNotes = rtbInternalNotes.Text
gOrder.OrderCancelled = chCancel.Checked
gOrder.CommTotal = CDec(txtCVal.Text)
gOrder.CommVAT = CDec(txtCVat.Text)
Dim dtLines As New DataTable
dtLines = ugProducts.DataSource
Dim dsLines As New DataSet
dsLines.Tables.Add(dtLines.Copy)
Select Case gOrder.Stage
Case 4
Dim proceed As Integer = 0
For Each ugr As UltraGridRow In ugProducts.Rows
If ugr.Cells("Goods_Delivered").Value = False Then
If IsDBNull(ugr.Cells("Final_Delivery").Value) = False Then
ugr.Cells("Final_Delivery").Value = DBNull.Value
End If
If isamend = False Then
MsgBox("Unable to proceed to next stage until supplier(s) goods have been delivered", MsgBoxStyle.OkOnly, "Goods not delivered")
End If
proceed = proceed + 1
End If
If dtFreight Is Nothing Then
gOrder.Save(dsLines, , dtfCleared, isClear)
If chCancel.Checked = True Then
Try
Dim f As New frmOrder(con, False, True, currentUser, , admin)
f.MdiParent = Me.ParentForm
f.Show()
Catch ex As Exception
errorLog(ex)
End Try
End If
I tried added Me.Close() at both the start and end of the Try, however, both kept giving me the error message of
Enumerator has been exhausted.
at Infragistics.Shared.SparseArray.CreateItemEnumerator.EnsureNotExhausted()
at Infragistics.Shared.SparseArray.CreateItemEnumerator.System.Collections.IEnumerator.MoveNext()
at Infragistics.Win.UltraWinGrid.RowEnumerator.MoveNext()
EDIT
I think that it's because the save routine is being called from another subroutine. The save button being pressed calls the subroutine that deals with the button press of another button, and this code is that subroutine.
But, even when changing this code to the actual code which is in the button click (removing the indirectness), it still happens?
So, how can I make it possible to close the existing form at the same time as opening the new one? Also, bare in mind that form being opened and the existing form are the same form, frmOrder, except that the existing form had data in it and thus some aspects were a little different.
Thanks
You've pretty much solved the problem in your edit.
Initially it would have been that too many subs were in use/open at once. Moving it hasn't worked now because it's still in the Select Case.
If you move the Me.Close() to outside of the Select Case, then it will work fine.

Nested If / Else

So I have a sub on a button click that does the following:
If the text entry within a combo box (cmbServerInstall.Text) is blank, firstly it will force the user to make a selection before proceeding.
Else, a string (strGameServer) is populated with the text within the combo box (cmbServerInstall.Text).
From here, a MessageBox will then show with a Yes/No option, asking if the user wishes to proceed.
Here is where things are going wrong.
What I want to happen
If the user selects yes, then I want to use another if/else to determine what was stored in the string strGameServer. Depending on what this is set to, it will launch one of two batch files (I understand the file paths are the same at the moment, I plan to update this at a later date).
If the user selects no, I want it to remove the selection from the combobox cmbServerInstall.
What is happening as it stands
Basically the shell command launches the batch file REGARDLESS of whether or not MsgBoxResult is Yes or No.
Could anyone kindly take a look at the code below and point me in the direction of where I am going wrong? Nested IFs seem to be getting the better of me.
Dim strGameServer As String
If cmbServerInstall.Text = "" Then
MessageBox.Show("Please select a game server to install", "No game server selected", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1)
Else
strGameServer = cmbServerInstall.Text
MessageBox.Show("You have chosen" + " " + strGameServer + "." + " " + "Please confirm you wish to proceed with your selection.", "Confirm game server selection", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1)
If MsgBoxResult.Yes Then
If strGameServer = "Counter-Strike: Global Offensive" Then
Shell("C:\Users\Damon\Desktop\YorkshaLAN Server Creator\YorkshaLAN Server Setup.bat", AppWinStyle.NormalFocus)
Else : strGameServer = "Team Fortress 2"
Shell("C:\Users\Damon\Desktop\YorkshaLAN Server Creator\YorkshaLAN Server Setup.bat", AppWinStyle.NormalFocus)
End If
Else
cmbServerInstall.Text = ""
End If
cmbServerInstall.Text = ""
cmbServerInstall.Enabled = False
btnServerGoInstall.Enabled = False
End If
End Sub
You need to save the result from MessageBox.Show and then check it, or do so in one line.
Edit of original code:
If cmbServerInstall.Text = "" Then
MessageBox.Show("Please select a game server to install", "No game server selected", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1)
Else
Dim strGameServer As String = cmbServerInstall.Text ' Moved init to avoid declaration without use '
If MessageBox.Show("You have chosen" & " " & strGameServer & "." & " " & "Please confirm you wish to proceed with your selection.",
"Confirm game server selection",
MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) =MsgBoxResult.Yes Then
If strGameServer = "Counter-Strike: Global Offensive" Then
Shell("C:\Users\Damon\Desktop\YorkshaLAN Server Creator\YorkshaLAN Server Setup.bat", AppWinStyle.NormalFocus)
Else
strGameServer = "Team Fortress 2"
Shell("C:\Users\Damon\Desktop\YorkshaLAN Server Creator\YorkshaLAN Server Setup.bat", AppWinStyle.NormalFocus)
End If
Else
cmbServerInstall.Text = ""
End If
cmbServerInstall.Text = ""
cmbServerInstall.Enabled = False
btnServerGoInstall.Enabled = False
End If
End Sub
You need to get the result of the MessageBox with the question and check the result
Dim result = MessageBox.Show("You have chosen ......")
If result = MsgBoxResult.Yes Then
.....
Actually your code checks the enum MsgBoxResult.Yes and because it is not zero the if is always evaulated as true
Also, if I were you I would try to remove any usage of the old VB6 syntax and enumerations. Actually MessageBox.Show returns a DialogResult enumeration not a MsgBoxResult. This is here just for VB6 compatibility
Dim result = MessageBox.Show("You have chosen ......")
If result = DialogResult.Yes Then