Creating error macro - vba

I currently have a macro that will deliver a pop up in the event that a field is left blank. The problem that I have is, once you acknowledge the error, it goes away and lets you proceed without filling in the field. Does anyone know what I am missing in the macro? I won't post the entire script because it is very long but it currently looks like this...
If Range("L58") = "Sigma Network" And Range("M58") = "" Then MsgBox "Please enter cable length "
Can I create one script that will work for all of the others or does each need to have its own?

Very simply, something like:
If Range("L58") = "Sigma Network" And Range("M58") = "" Then
Range("M58").Value = InputBox("Please enter cable length ", "Input value!", 0)
End If
You would of course need additional logic to prevent the user from entering a 0-value or empty string, etc.,
If you're doing this on for example, 50 different pairs of cells, (say L58 to L107 and M58 to M107 for example) this is a basic loop structure that you could use:
Dim cl as Range
For Each cl in Range("L58:L107")
If cl.Value = "Sigma Network" and cl.Offset(0,1).Value = "" Then
cl.Offset(0,1).Value = GetValue("Please enter cable length ", "Input value!", 0)
End If
Next
The loop can be further refined (e.g., if "Sigma Network" isn't the only thing you're checking for, or if you need different message text for the input box based on some other conditions, etc.
This will require the custom GetValue function which invokes the InputBox prompt, and configured to prevent 0-value input from the user. Additional logic may be required to prevent other types of data entry.
Function GetValue(msg as String, _
Optional title as String = "", _
Optional default as Double = 0)
'Function that calls the InputBox method
Dim ret
Do Until ret <> 0
ret = InputBox(msg, title, default)
Loop
GetValue = ret
End Function

Related

Access Public Function for Maintain Combo Lists

I have over 40 combo controls in my application. I am working on developing a public function, to put in the not in list event of every combo. The goal is to have 1 continuous pop up form, which will open, if the user says they want to add a new value to the combo. The open form command will pass open args for the
record source
the control source for the 1 text box on the continuous form (generically the type)
the label for the control source.
I'm having some trouble getting it to pass the open args. I debug.print the parts of the args, I can split them, when they get passed (inconsistent results getting the open args to pass correctly, as I try to debug), and I cannot seem to set the record source for the pop up form correctly. I've tried doing 1 at a time, and still can't seem to get it.
This is the public function:
Option Explicit
Public Function TypeNotInList(ctl As Control, arg1 As String, arg2 As Variant, arg3 As String)
On Error GoTo Err_TypeNotInList
Dim Msg, Style, Title
'arg1 is the row source of the combo, to be passed as the recordsource for the frmAddTypeVal form
'arg2 is the control source of the combo, to be passed as the control source for the text box in the frmAddTypeVal form
'arg3 is the label of the combo, to be used for messages, and the label of the text box in the frmAddTypeVal form
Msg = "The " & arg3 & " you entered is not in the " & arg3 & " list, would you like to add it now?"
Style = vbYesNo
Title = "Type or listing must be maintained"
Response = MsgBox(Msg, Style, Title)
If Response = vbYes Then
ctl.Undo
DoCmd.OpenForm "frmAddTypeVal", acNormal, , , , acDialog, arg1 & "|" & arg2 & "|" & arg3
ctl.Requery
End If
Exit_TypeNotInList:
Exit Function
Err_TypeNotInList:
MsgBox Err.Description
Resume Exit_TypeNotInList
End Function
This is how I am calling it, in 1 combo's Not In List event:
Option Explicit
Private Sub FKAuditType_NotInList(NewData As String, Response As Integer)
Dim a1 As String
Dim a2 As String
Dim a3 As String
a1 = Me.FKTypeXYZ.RowSource
a2 = "txtXYZType"
a3 = Me.lblTypeXYZ.Caption
TypeNotInList Me.FKTypeXYZ, a1, a2, a3
Response = acDataErrContinue
End Sub
That should be calling the public function, and passing the 4 parameters.
This is the form load of the generic continuous pop-up form, called frmAddTypeVal:
Option Explicit
Private Sub Form_Load()
Dim VarArgs() As String
VarArgs = Split(Me.OpenArgs, "|")
Me.Form.RecordSource = VarArgs(0)
Me.txtType.ControlSource = VarArgs(1)
Me.lblType.Caption = VarArgs(2)
End Sub
When I run this as is, my debug.print (s) give me the following:
ctl = FKFKTypeXYZ
arg1 = SELECT tblXYZType.ID, tblXYZType.txtXYZType FROM tblXYZType ORDER BY tblXYZType.txtXYZType;
arg2 = FKXYZType
arg3 = XYZ Type
openargs =
I get each value, but the open args is null. What the heck, Beck?
Can anyone help guide this clueless coder? lol
Thanks!
I edited this to update the code, with the changes made. Now it's working! At least the first part of the process. The openargs get passed and the pop-up form works correctly. When I click close on that form, I'm back on the form with the notinlist combo. That resumes it's process and I get a message: The text you entered isn't an item in the list.
It know that's the default notinlist message. The thing is, the public function is supposed to handle this. It has, in the if Response = vbYes Then
ctl.undo
'undo trying to add a value that is not in the list yet
and then after the open form (which would involve the close of that form, I would think)
ctl.requery
'requery the combo, so the added value(s) can be seen
Anyone know how I can adjust this to prevent that message, but not just disable all warnings?
Thanks!
Got it! In the not in list, after I call the public function, I have to add:
Response = acDataErrContinue
This let's the default error message take a seat lol.
Thanks for all the help! This is going to make setting this up for every darn combo so much easier!!!!

Retrieving weights from scales to excel

I have connected a weighing scale to my PC via an RS-232 to USB converter cable. My goal was to create a command button in excel 2007 that would place the weight from the scale into the selected cell. I got it to work using the following code in a userform.
Private Sub XMCommCRC1_OnComm()
Static sInput As String
Dim sTerminator As String
Dim Buffer As Variant
' Branch according to the CommEvent property
Select Case XMCommCRC1.CommEvent
Case XMCOMM_EV_RECEIVE
Buffer = XMCommCRC1.InputData ' Use Input property for MSComm
sInput = sInput & Buffer
If Worksheets("Settings").Range("Terminator") = "CR/LF" Then
sTerminator = vbCrLf
Else
sTerminator = vbCr
End If
If Right$(sInput, Len(sTerminator)) = sTerminator Then
XMCommCRC1.PortOpen = False
sInput = Left$(sInput, Len(sInput) - Len(sTerminator))
Select Case Left$(sInput, 2)
Case "ST", "S "
ActiveCell.Value = CDbl(Mid$(sInput, 7, 8))
ActiveCell.Activate
Case "US", "SD"
MsgBox "The balance is unstable."
Case "OL", "SI"
MsgBox "The balance is showing an eror value."
End Select
sInput = ""
End If
End Select
End Sub
Public Sub RequestBalanceData()
With Worksheets("Settings")
' Configure and open the COM port
If Not XMCommCRC1.PortOpen Then
XMCommCRC1.RThreshold = 1
XMCommCRC1.RTSEnable = True
XMCommCRC1.CommPort = .Range("COM_Port")
XMCommCRC1.Settings = .Range("Baud_Rate") & "," & _
.Range("Parity") & "," & _
.Range("Data_Bits") & "," & _
.Range("Stop_Bits")
XMCommCRC1.PortOpen = True
End If
' Send balance's "SI" (Send Immediate) command
' to request weighing data immediately
If .Range("Terminator") = "CR/LF" Then
XMCommCRC1.Output = "R" & vbCrLf
Else
XMCommCRC1.Output = "R" & vbCr
End If
End With
End Sub
I then created a command button with the following code.
Private Sub CommandButton1_Click()
UserForm1.RequestBalanceData
End Sub
When I click on the command button the weight is placed in the selected cell. However, this does not consistently happen. Sometimes when I click the button nothing will be placed in the cell, and I will have to click it multiple times until the weight is placed in the cell. I would like to fix this, but I'm not sure where to start. Is it a problem with the code itself, or is it more likely a problem with the converter or the scale itself?
Any help is appreciated.
Here is the scale: https://www.optimascale.com/product-page/op-915-bench-scale
Here is the converter cable: https://www.amazon.com/gp/product/B06XJZHCV8/ref=ox_sc_act_title_3?smid=A33N7O64F8FSDL&psc=1
Here is the tutorial I used for the code: http://www.msc-lims.com/lims/diybalance.html
Here is the ActiveX control from the tutorial that I used: http://www.hardandsoftware.net/xmcomm.htm
EDIT: I have done what Wedge has suggested and placed a Mgsbox sInput after my first End If. I have been getting inconsistent results. I am wondering if I need to change my scales sending format. The scale is currently set to sending format 4.
Here is the scale manual (sending formats are on page 21-23: https://docs.wixstatic.com/ugd/78eff6_e629ae5fe7004c7189060cca4bc7c3de.pdf
2ND EDIT:
I have connected my serial port to putty. My scale is in continuos sending mode. In putty the scale is consistently sending the following: ST,GS+ 0.00lb. However, when i try to enter the weight value in a cell, the message box sometimes displays that part of the data sent (ST,GS+ 0.00lb) has got cut off, or has been sent multiple times with one button press. Does anyone know how I would fix this?
3RD EDIT: It seems to me that the continuous sending mode (mode 4) my scale is set to is sending data too fast and is causing my code to mess up. I would like to try to make this work with the command request mode (mode 3), but I can't figure out how to properly parse the data string and place it into a cell. The sending format for command request mode is :
If anybody could help me figure out how to get this working I would greatly appreciate it.

Getting .value property when using a string and variable

I am creating a form in Access which will be used as an order sheet for classroom materials. I have the available resources listed and a text box next to the resource where the user inputs the quantity they desire.
My VBA code checks to see if any entries have been made by using the following. (I am using Nz() to allow for Null results):
QuantCheck = Nz(Box1.Value, 0) + Nz(Box2.Value, 0) + Nz(Box3.Value, 0)
Where "QuantCheck" is the variable I am using in the IF statement which begins the workflow:
If QuantCheck > 0 Then
I would like to clean this up by using some kind of loop statement, however I am not able to extract the .value from a string. I would love something like the following which I could incorporate into a loop:
"Box"&VariableNumber.Value
From what I can tell, I am not able to use a string (concatenated or otherwise) as the base for the .value call.
It is interesting that there is a way to accomplish this when using a SQL statement. I have this elsewhere in the code which works nicely:
SQLStr = "INSERT INTO OrderRequests VALUES (cbSchool, txtName, Title" & x & ".caption, Box" & x & ")"
Here I have a variable "x" which increases with each loop to change the Title line, and the Box line.
Any help is appreciated.
I suggest you use the Tag property of the controls. Put "QuantCheck" in the Tag property of any control you want to include. Then
Function QuantitiesExist(frm As Form) As Boolean
Dim Ctrl As Control
Const sQUANTCHK As String = "QuantCheck"
For Each Ctrl In frm.Controls
If Ctrl.Tag = sQUANTCHK Then
If Nz(Ctrl.Value) > 0 Then
QuantitiesExist = True
Exit For
End If
End If
Next Ctrl
End Function
Now you get self documenting code
If QuantitiesExist(Me) Then
And when you add/delete/change controls, you don't have to edit your code. Just set up new controls with the proper tags.
You could loop through the control on the for checking the names and then if it is the one you wanted take an action on it, is this what you was thinking of?
Dim Ctrl As Control
For Each Ctrl In Me.Controls
If Ctrl.Name = "TxtPath" Then ' "Box" & VariableNumber Then
MsgBox Ctrl.Value
End If
Next

VBA Code to Create Lotus Notes Email - CC Emails Not Working

I have some VBA code that takes the various email parts as inputs and creates an email message in Lotus Notes, and sends it from a group mailbox. It sends the email out to a recipient and CC recipients, and then leaves a copy of the message in the "Sent" box of a group email account. I think the sent message in that box is sort of a dummy, as it is perhaps not the exact message as it was sent.
This works, and sends the message to the SendTo, and to the first CC address. However, if I have a second CC address, it turns the ending of the second address into gibberish. For example, if the SendTo is "mike#someemail.com", and the CC is "john#someemail.com, jim#someemail.com"... in the Sent box it appears to have sent it to mike#someemail.com, and CC to john#someemail.com and jim#someemail.com. However, the actual mail is only received by john, and the CC looks like this: "john#someemail.com, jim#pps.rte_to_v" and jim never gets the message.
On another message, the second CC ends up being jim#vwall11.com. I haven't found a pattern to the gibberish it puts at the end of the CC line instead of the correct address. It took us awhile to learn about the problem since it looks correct in the Sent mailbox.
Here's the code I'm using. I'm changing the server names, etc, but all relevant code is intact.
Private Sub TestEmail()
Call EmailFromADT("mike#somemail.com", "john#somemail.com, jim#somemail.com", "test subject", "test message", _
"", "", "", "")
End Sub
Function EmailFromADT(strSendTo As String, strCopy As String, strSubject As String, _
strText1 As String, strText2 As String, strText3 As String, _
strText4 As String, strText5 As String)
Dim notesdb As Object
Dim notesdoc As Object
Dim notesrtf As Object
Dim notessession As Object
Dim i As Integer
Set notessession = CreateObject("Notes.Notessession")
''''''''Group Mailbox'''''''''''''''''''''''''''''''''''''''''''''''''
Set notesdb = notessession.GetDatabase("servername", "mailin\notesaddr.nsf")
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Open the mail database in notes
If notesdb.IsOpen = True Then
'Already open for mail
Else
notesdb.OPENMAIL
End If
Set notesdoc = notesdb.CreateDocument
Call notesdoc.ReplaceItemValue("Subject", strSubject)
Set notesrtf = notesdoc.CreateRichTextItem("body")
Call notesrtf.AppendText(strText1 & vbCrLf & strText2 & vbCrLf & strText3 & vbCrLf & strText4 & vbCrLf & strText5)
notesdoc.SendTo = strSendTo
notesdoc.CopyTo = strCopy
notesdoc.from = UserName()
''''''''Group Mailbox'''''''''''''''''''''''''''''''''''''''''''''''''
notesdoc.principal = "Group Team"
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
notesdoc.BlindCopyTo = strBCC
Call notesdoc.Save(True, False)
notesdoc.SaveMessageOnSend = True
Call notesdoc.Send(False, strSendTo)
Set notessession = Nothing
End Function
To have multiple values in an item in a Document, you need to use an array.
Try this:
dim varCopyTo as Variant
varCopyTo = Split( strCopyTo, "," )
call notesDoc.Replaceitemvalue( "CopyTo", varCopyTo )
You could also write notesDoc.CopyTo=varCopyTo, but it is better (more secure, slightly better performance) to use ReplaceItemValue.
In addition you should add Call notesDoc.ReplaceItemValue("Form", "Memo" ) after creating the document, so that the server/client does not have to "guess" what kind of document you are creating.
notesdoc.CopyTo wants an array, not a comma-delimted string on the right hand side of the assignment. Each element in the array should be an individual address. By passing in a comma-delimited string, you're essentially passing in a single invalid address as far as Notes and Domino are concerned. I'm not entirely sure why that's being transformed in the peculiarly random way that it is, but I am sure it's definitely not going to be right that way.
And better than using the shorthand form (notesdoc.CopyTo = ...) for this code, you should probably be using Call notesdoc.ReplaceItemValue, like you do with the Subject, but passing in an array there.

vb.net Input Box Function

I am using an input box. In tat am getting the number as input. When the user presses OK the program is workin. But when I press the cancel button am getting a error message
" Conversion from String "" to 'Integer' type is not valid "
If i press cancel I need the program to end.
and also i want to know how to move to other form when i press cancel in input box
Its probably a good idea to use try parse for these situations it handles more cases than empty strings for example non numeric characters characters
Dim number As Integer
Dim result As Boolean = Int32.TryParse(inputBox.Text, number)
if Not result Then
number = 0
End If
If user didn't enter anything in the input box and press cancel, it will be an empty string. Your system won't be able to convert an empty string to integer. Therefore, your program should handle this scenario with code similar to below.
If inputBox.Text = "" Then
inputValue = 0
Else
inputValue = inputBox.Text