How do I assign inputbox input to variable for each vba excel - excel

I have a for statement in a VBA script that goes through each cell in a range (number of cells in range is variable based on user input - could be three cells could be 100). Each instance of the for loop calls an input box. How do I assign the user input from each instance of the for loop to a variable for later use?
Here is the for with the input box:
For Each cell In MyQCData
text_string = cell.Value
WrdArray() = split(text_string, ",")
For i = LBound(WrdArray) To UBound(WrdArray)
strg = strg & vbNewLine & "Part No. " & i & " - " & WrdArray(i)
Next i
InputBox ("This part requires a " & WrdArray(0) & " measurement of the " & _
WrdArray(1) & vbNewLine & vbNewLine _
& "The range for this is input is " & vbNewLine & vbNewLine & "Lower Control Limit " _
& WrdArray(2) & vbNewLine & "Upper Control Limit " & WrdArray(3))
Erase WrdArray()
Next cell

Yes, use an array:
Dim inputBoxAnswers() As String
ReDim inputBoxAnswers(1 To MyQCData.Cells.Count)
Dim cellCounter As Long
For Each cell In MyQCData
text_string = cell.Value
WrdArray() = split(text_string, ",")
'Is this loop needed???
For i = LBound(WrdArray) To UBound(WrdArray)
strg = strg & vbNewLine & "Part No. " & i & " - " & WrdArray(i)
Next i
cellCounter = cellCounter + 1
inputBoxAnswers(cellCounter) = InputBox("This part requires a " & _
WrdArray(0) & " measurement of the " & _
WrdArray(1) & _
vbNewLine & vbNewLine & _
"The range for this is input is " & _
vbNewLine & vbNewLine & _
"Lower Control Limit " & WrdArray(2) & _
vbNewLine & _
"Upper Control Limit " & WrdArray(3))
Next cell
If your MyQCData range is not a single column or a single row, you may find it easier to use a two-dimensional array, which could (perhaps) be dimensioned using
Dim inputBoxAnswers() As String
ReDim inputBoxAnswers(1 To MyQCData.Rows.Count, 1 To MyQCData.Columns.Count)
but then you will need to rework the indexes to use when assigning the elements their values. It would probably need to be
inputBoxAnswers(cell.Row - MyQCData.Row + 1, cell.Column - MyQCData.Column + 1) = ....
but a lot depends on how you intend to use the array afterwards.

It's kind of hard to tell without the rest of your code, but I assume that MyQCData is a Range. Try the below. I sort of "brute forced" the Inputbox look with k, FYI.
Dim k As Long
k = 0
Dim inputArr() As Variant
ReDim inputArr(myqcdData.Cells.Count)
For Each cell In MyQCData
text_string = cell.Value
WrdArray() = Split(text_string, ",")
For i = LBound(WrdArray) To UBound(WrdArray)
strg = strg & vbNewLine & "Part No. " & i & " - " & WrdArray(i)
Next i
inputArr(k) = InputBox("This part requires a " & WrdArray(0) & " measurement of the " & _
WrdArray(1) & vbNewLine & vbNewLine _
& "The range for this is input is " & vbNewLine & vbNewLine & "Lower Control Limit " _
& WrdArray(2) & vbNewLine & "Upper Control Limit " & WrdArray(3))
k = k + 1
Erase WrdArray()
Next cell
'Check each value in the array. This is optional and can be removed/commented out
For k = LBound(inputArr) To UBound(inputArr)
Debug.Print inputArr(k)
Next k
Edited per #Yow's astute comment

I'm going to dress this in a standalone code that you can easily run to get a feel for what's going on. Array variables must be declared hence Dim userInput(99) and the 99 is the upper limit (0-99 = 100 possible values). The first line of the first loop sets the variables, that's userInput(j) = InputBox("Sample InputBox", "InputBox Title", "blah" & j) the "blah" & j bit is the default entry, which is useful when you're writing/debugging as it's a lot faster to keep entering dummy data...
Sub inputBoxEg()
Dim userInput(99)
Dim MyQCData As Range
Set MyQCData = Range("A1:A4")
'Set InputBox inputs to a variable array called userInput:
j = 0
For Each cell In MyQCData
userInput(j) = InputBox("Sample InputBox", "InputBox Title", "blah" & j)
If userInput(j) = "" Then Exit Sub 'if user pressed cancel or entered blank
j = j + 1
Next cell
'Collate variables collected by InputBoxes in a text string called allInputs:
allInputs = ""
For i = 0 To j - 1
If i = 0 Then
allInputs = i & ": " & userInput(i)
Else
allInputs = allInputs & vbNewLine & i & ": " & userInput(i)
End If
Next i
MsgBox allInputs
End Sub

Related

Checking datatype in excel VBA

I wrote a code that checks whether the entered data is numeric with the isNumeric function. Now i want to specify and check whether it is an Integer. As far as i know, there is no function like isInteger. How can I check the datatype?
I posted a snippet of the code below, I hope it makes sense like this. If not please let me know.
Thank you for your help!
Sub CheckColumnsHardwareDefinition()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Hardware Definition")
Dim Target As Range
Dim Target2 As Range
Dim lr As Long
Dim lr2 As Long
Dim DblLengthMin As Double
Dim DblLengthMax As Double
Dim DblWeightMin As Double
Dim DblWeightMax As Double
Dim dynamicArray1() As String
Dim dynamicArray2() As String
Dim f1 As Integer
Dim f2 As Integer
f1 = 0
f2 = 0
DblLengthMax = 20000
DblLengthMin = 5
DblWeightMin = 0.0001
DblWeightMax = 10000
lr3 = Application.WorksheetFunction.Max( _
ws.Range("A" & ws.Rows.Count).End(xlUp).Row, _
ws.Range("B" & ws.Rows.Count).End(xlUp).Row, _
ws.Range("C" & ws.Rows.Count).End(xlUp).Row, _
ws.Range("D" & ws.Rows.Count).End(xlUp).Row, _
ws.Range("E" & ws.Rows.Count).End(xlUp).Row, _
ws.Range("F" & ws.Rows.Count).End(xlUp).Row)
For Each Target3 In Range("A2:F" & lr3)
If IsEmpty(Target3) Then
Target3.Interior.ColorIndex = 8
End If
Next Target3
lr = Application.WorksheetFunction.Max( _
ws.Range("C" & ws.Rows.Count).End(xlUp).Row, _
ws.Range("D" & ws.Rows.Count).End(xlUp).Row, _
ws.Range("E" & ws.Rows.Count).End(xlUp).Row)
For Each Target In Range("C2:E" & lr)
If **Not IsNumeric(Target)** Then
f1 = f1 + 1
Target.Interior.ColorIndex = 3
ReDim Preserve dynamicArray1(0 To f1)
dynamicArray1(f1) = "Row " & Target.Row & " Column " & Target.Column & " wrong
entry: " & Target.Value
End If
If **IsNumeric(Target)** And Target.Value > DblLengthMax Or Target.Value <
DblLengthMin
Then
f2 = f2 + 1
Target.Interior.ColorIndex = 46
ReDim Preserve dynamicArray2(0 To f2)
dynamicArray2(f2) = "Row " & Target.Row & " Column " & Target.Column & " wrong
entry: " & Target.Value
End If
Next Target
Inhalt1 = Join(dynamicArray1, vbCrLf)
MsgBox ("Wrong datatype! " & vbCrLf & vbCrLf & f1 & " Datatype Errors (marked
red)" & vbCrLf & "Only numbers can be entered. Check again" & vbCrLf & Inhalt1)
Inhalt2 = Join(dynamicArray2, vbCrLf)
MsgBox ("Entries out of range!" & vbCrLf & vbCrLf & f2 & " Range errors (marked
orange)" & vbCrLf & "The value is out of range. Check for unit [mm] " & vbCrLf &
Inhalt2)
End Sub
Let's take advantage of the "internal" casting of VBA
Function isInteger(val As Variant) As Boolean
Dim i As Integer
On Error GoTo EH
i = CInt(val)
If i = val Then ' check if it was cut or not
isInteger = True
Else
isInteger = False
End If
Exit Function
EH:
isInteger = False
End Function
As i was declared as integer i=val will cause an overflow and therefore the result is FALSE for 33000. If you do not want that you have to declare i as long and use CLng()
A short version would look like that
Function isInteger(val As Variant) As Boolean
On Error GoTo EH
isInteger = (val = CInt(val))
Exit Function
EH:
End Function

Data validation for certain columns between other columns only

Hey guys I am trying to change a code that I wrote for an excel vba Data validation tool. This is the first table i used:
Now I have another table with additional variables :
When I reuse the code from the first one (shown below) the columns on the right of length/width and height are also checked. I only want the three columns to be checked. I tried setting the variable lCol to 3 but then only C2 and the values below are checked. How can i apply the code only to the columns B/C/D without including the ones on the right without changing up the code completely?
Any help is appreciated!
Sub CheckColumnsTransportationMean()
Dim rng As Range
Dim lCol As Long, lRow As Long
Dim DblLengthMin As Double
Dim DblLengthMax As Double
Dim dynamicArray1() As String
Dim dynamicArray2() As String
Dim f1 As Integer
Dim f2 As Integer
f1 = 0
f2 = 0
ReDim Preserve dynamicArray1(0)
ReDim Preserve dynamicArray2(0)
DblLengthMax = 20000
DblLengthMin = 5
lCol = Range("C2").End(xltoRight).Column
lRow = Range("C2").End(xlDown).Row
For Each rng In Range("C2", Cells(lRow, lCol))
If IsNumeric(rng) = False Then
f1 = f1 + 1
rng.Interior.ColorIndex = 3
ReDim Preserve dynamicArray1(0 To f1)
dynamicArray1(f1) = "Row " & rng.Row & " Column " & rng.Column & " wrong
entry: " & rng.Value
End If
If IsNumeric(rng) And rng.Value > DblLengthMax Or rng.Value < DblLengthMin Then
f2 = f2 + 1
rng.Interior.ColorIndex = 46
ReDim Preserve dynamicArray2(0 To f2)
dynamicArray2(f2) = "Row " & rng.Row & " Column " & rng.Column & " wrong entry: " &
rng.Value
End If
Next rng
Inhalt1 = Join(dynamicArray1, vbCrLf)
MsgBox ("Wrong datatype! " & vbCrLf & vbCrLf & f1 & " Datatype Errors (marked red)" &
vbCrLf & "Only numbers can be entered. Check again" & vbCrLf & Inhalt1)
Inhalt2 = Join(dynamicArray2, vbCrLf)
MsgBox ("Entries out of range!" & vbCrLf & vbCrLf & f2 & " Range errors (marked
orange)" & vbCrLf & "The value is out of range. Check for unit [mm] " & vbCrLf &
Inhalt2)
End Sub

Comparing Sheet's Cell Data is not working in Excel VBA

Option Explicit
Private Sub CommandButton1_Click()
'//this macro checks whether two sheet's data is correspondent.
Dim i1 As Integer
Dim i2 As Integer
For i2 = 1 To i2 = 31
For i1 = 1 To i1 = 27
If ThisWorkbook.Worksheets(UserForm2.TextBox1.Value).Cells(i1, i2).Value <> _
ThisWorkbook.Worksheets(UserForm2.TextBox2.Value).Cells(i1, i2).Value Then
MsgBox "Value of " & i1 & "rows " & i2 & "column : " & Chr(13) & Chr(10) _
& UserForm2.TextBox1.Value & " sheets : " & ThisWorkbook.Worksheets(UserForm2.TextBox1.Value).Cells(i1, i2).Value & Chr(13) & Chr(10) _
& UserForm2.TextBox2.Value & " sheets : : " & ThisWorkbook.Worksheets(UserForm2.TextBox2.Value).Cells(i1, i2).Value
End If
Next
Next
MsgBox "End"
End Sub
Above is My Code.
Its function is Simple.
It receives two sheet's name from UserForm TextBox
And Check whether two sheets has same content
But, it don't work, even with no error message.
I pressed the button but it didnt response.
Just "End" Message pops up.
How can I solve this problem?
Thank you for you answer in advance.
This is more by way of an extended comment.
See the following as a re-write (I have not tested) but shows how you can use variables to store the values and therefore be more efficient. I suggest you step through the code checking the values of each of the variables (in the locals window or with watches) and make sure they are as you expect. Run some cases you expect to see fail and insert break on change in values for your watch values perhaps? References here for debugging.
Private Sub CommandButton1_Click()
'//this macro checks whether two sheet's data is correspondent.
Dim i1 As Long
Dim i2 As Long
Dim text1 As String
Dim text2 As String
text1 = UserForm2.TextBox1.Value
text2 = UserForm2.TextBox2.Value
Dim testSheet1 As Worksheet
Dim testSheet2 As Worksheet
testSheet1 = ThisWorkbook.Worksheets(text1)
testValue2 = ThisWorkbook.Worksheets(text2)
For i2 = 1 To 31
For i1 = 1 To 27
If testSheet1.Cells(i1, i2).Value <> testSheet2.Cells(i1, i2).Value Then
MsgBox "Value of " & i1 & "rows " & i2 & "column : " & Chr(13) & Chr(10) _
& text1 & " sheets : " & testSheet1.Cells(i1, i2).Value & Chr(13) & Chr(10) _
& text2 & " sheets : : " & testSheet2.Cells(i1, i2).Value
End If
Next i1
Next i2
MsgBox "End"
End Sub

how to get your answers to show up on a new page

The totals show up on a message box and I want them on a new sheet in excel.
'Output totals to a message box
sTtl = "Total stock at " & dStk & " = " & TotStk
sMsg = "Board No." & vbTab & "Cut Lenght" & vbCrLf
For k = LBound(DetStk, 2) To UBound(DetStk, 2)
sMsg = sMsg & DetStk(0, k) & vbTab & vbTab _
& DetStk(1, k) & vbCrLf
Next k
MsgBox sMsg, vbOKOnly, sTtl
End Sub
The code below will create a new sheet and insert the data generated for the message box, including the title and headings, into 2 columns. You can comment out or delete the message box line msgbox sMsg, ..... if no longer want it to appear.
'Output totals to a message box
Sheets.Add After:=Sheets(Sheets.Count) ' create a new sheet
sTtl = "Total stock at " & dStk & " = " & TotStk
Range("A1").value = sTtl 'put th title in cell A1
sMsg = "Board No." & vbTab & "Cut Lenght" & vbCrLf
Range("A2").value = "Board No."
Range("B2").value = "Cut Lenght"
Range("A2:B2").Font.Bold = True ' format the headings bold (optional)
intRow = 3 ' set starting row below the heading row.
For k = LBound(DetStk, 2) To UBound(DetStk, 2)
sMsg = sMsg & DetStk(0, k) & vbTab & vbTab _
& DetStk(1, k) & vbCrLf
Range("A"&intRow).value = DetStk(0, k)
Range("B"&intRow).value = DetStk(1, k)
intRow = intRow + 1 'add 1 to move to the next row.
Next k
MsgBox sMsg, vbOKOnly, sTtl 'you can delete this line or comment it out with "'" if you don't want to display the message box.
End Sub

Show all rows that meet a certain criteria in a pop up window

I am trying to create a pop up that returns either an entire row of data or just the first 3 columns whenever column E is greater than 1. The tricky part is that this has to happen when the "close" button in an another popup that collects data is clicked.
So far I can only get it to return each record in a separate popup by using a loop but I would like to show all cases in the same pop up. Here's what I have:
column A is is Last Name
column B is First Name
column C is a location number
column D is a date
column E is a simple count cell that shows how many times a First and Last Name occur
Private Sub cmdClose_Click()
Dim wsx As Worksheet
Set wsx = Worksheets("SuspectData")
Dim xRow As Long
Dim countingX As Integer
countingX = 2
'find last row in database'
xRow = wsx.Cells.Find(What:="*", SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlValues).Row
'prompt warning'
With wsx
Do While countingX <= xRow
If Range("E" & countingX) > 1 Then
MsgBox ("Suspect " & Range("B" & countingX) & " " & Range("A" & countingX) & " at Unit " & Range("C" & countingX))
End If
countingX = countingX + 1
Loop
End With
Unload Me
End Sub
Thank you!
If you want all cases to return inside of one popup, you should add the cases to a string, and have the popup call the string outside of the loop
Dim s as String
s = ""
Do While countingX <= xRow
If Range("E" & countingX) > 1 Then
s = s & vbnewline & "Suspect " & Range("B" & countingX) & " " & Range("A" & countingX) & " at Unit " & Range("C" & countingX)
End If
countingX = countingX + 1
Loop
MsgBox s

Resources