for....next loop failed after repeat userform - excel

I'm using for next loop with while wend loop inside of it. the problem is when I enter first data and then I want to repeat inserting by choosing vbYes,the loop will repeat but it set the value to i=32 again and proceed while loop eventhough the while{condition} is false.let me give some example,
comboBox1.value = {a,b,c,d}
i={32,33,34,35} ~> i is set to row number.
for the first count,I insert c to combobox1 giving combobox1.value=c and cells(34,2).value=c hence while loop proceed. but when I choose to continue inserting data for second time, it go back to for next loop again but it set the value of i=32, giving cells(32,2).value=c and then proceed to while loop but the while loop suppose to not proceed because the correct value for cells(32,2).value=a . can anyone help?
Dim i As Long
Dim prod As String
Dim RowNo As Long
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Application.ScreenUpdating = False
prod = ComboBox1.Value
For i = 32 To 35
While ComboBox1.Value = Worksheets("Input").Cells(i, 2).Value
Rows(i).Select
Selection.Insert shift = xlDown
With Worksheets("Input")
'~insert data
.Range("B" & i) = ComboBox1.Text
.Range("C" & i) = TextBox1.Text
.Range("D" & i) = TextBox2.Text
.Range("E" & i) = TextBox3.Text
.Range("F" & i) = TextBox4.Text
.Range("G" & i) = TextBox5.Text
.Range("H" & i) = ComboBox2.Text
.Range("I" & i) = TextBox6.Text
.Range("J" & i) = TextBox7.Text
.Range("K" & i) = TextBox8.Text
End With
Workbooks(prod & " Input.xlsm").Activate
'~select row number from another worksheet
RowNo = Workbooks(prod & " Input.xlsm").Worksheets("Input").Cells(31, 3).Value
Set sh1 = Workbooks(prod & " Input.xlsm").Worksheets("Input")
Set sh2 = Workbooks("MasterInput.xlsm").Worksheets("Input")
'~copy inserted data from master input to product input
sh1.Range(sh1.Cells(RowNo, 2), sh1.Cells(RowNo, 11)).Value = sh2.Range(sh2.Cells((i, 2), sh2.Cells(i , 11)).Value
If MsgBox("One record written to Master Input. Do you want to continue entering data?", vbYesNo) = vbYes Then
GoTo repeat1:
Else
Unload Me
End If
Exit Sub
Wend
Next
Application.ScreenUpdating = True
repeat1:
End Sub

You are unloading form from memory.Unload the form when you dont want to continue..
if msgbox("you want to continue",vbyesNo)=vbyes then
goto repeat1
else
unload me
end if

lastly! just a simple one line command that i forgot to put.
insert above for loop
Workbooks("MasterInput.xlsm").Activate
For i = 32 To 35
works now! the i value taken from the second workbook where it suppose to take from first workbook.

Related

UserForm check the existing list before creating new data VBA

I want to create a userform with inputs: Name (TextBox1), Surname (TextBox2), Date of birth (TextBox3) and 1 output which would basically be their ID (goes from 1 to inf). What bothers me is that I want to code that if lets say Name and Surname already exists in database, msg will popup and form will reset else everything will be put to the table. I kind of managed to do that. Problem is now if I do put name and surname that already exists it wont input it in the table and it will show the message, but even if it doesn't exists the message will still pop up but it will input it in the table. This is the code:
Private Sub CommandButton1_Click()
Dim iRow As Long
Dim ws As Worksheet
Set ws = Sheet2
Dim a As Integer
Application.ScreenUpdating = False
iRow = ws.Range("A1048576").End(xlUp).Row + 1
If Not (TextBox1.Text = "" Or TextBox2.Text = "" Or TextBox3.Text = "") Then
With ws
Label1.Caption = iRow - 1
For a = 1 To iRow
If (ws.Cells(a, 2).Value = TextBox1.Value And ws.Cells(a, 3).Value = TextBox2.Value) Then
MsgBox "Values you entered already exists!"
Call Reset
Exit Sub
Else
.Range("A" & iRow).Value = Label1.Caption
.Range("B" & iRow).Value = TextBox1.Value
.Range("C" & iRow).Value = TextBox2.Value
.Range("D" & iRow).Value = TextBox3.Value
End If
Next a
End With
End If
Application.ScreenUpdating = True
End Sub
The problem is you are checking down to the row where the new record is inserted. So for every row that does not match the new record is inserted at iRow. When the loop gets to the end it checks iRow, matches and shows the message. Separate code into 2 steps, first check then update or reset.
Private Sub CommandButton1_Click()
If TextBox1.Text = "" Or TextBox2.Text = "" Or TextBox3.Text = "" Then
Exit Sub
End If
Dim ws As Worksheet
Dim iRow As Long, r As Long, bExists As Boolean
Set ws = Sheet2
iRow = ws.Cells(Rows.Count, "A").End(xlUp).Row
' check exists
For r = 1 To iRow
If (ws.Cells(r, 2).Value = TextBox1.Value) _
And (ws.Cells(r, 3).Value = TextBox2.Value) Then
bExists = True
Exit For
End If
Next
' update sheet
If bExists Then
MsgBox "Values you entered already exists!"
Call Reset
Exit Sub
Else
Label1.Caption = iRow
iRow = iRow + 1
With ws
.Range("A" & iRow).Value = Label1.Caption
.Range("B" & iRow).Value = TextBox1.Value
.Range("C" & iRow).Value = TextBox2.Value
.Range("D" & iRow).Value = TextBox3.Value
End With
End If
End Sub

Looping through two cell ranges in two worksheets

The following code runs but, not getting the results. The information is there in the correct range.
Dim ID As Range
Dim SN As Range
Dim i As Integer
Set ID = Sheet6.Range("B2:B8")
Set SN = Sheet2.Range("C7:C184")
For i = 2 To ID.Cells.count
If ID.Cells(i) = SN.Cells(i) Then
MsgBox "do something"
ID.Cells.Offset(0, 2).Value = SN.Cells.Offset(0, -2).Value
Else
MsgBox "sorry"
End If
Next
i found another code and modified it to my work sheet. This one works great.
Dim i As Long
Dim j As Long
For i = 2 To 40
If Sheet6.Range("C" & i).Value = "" Then
Exit For
End If
For j = 7 To 1000
If Sheet2.Range("c" & j).Value = "" Then
Exit For
End If
If Sheet6.Range("C" & i).Text = Sheet2.Range("c" & j).Text Then
Sheet6.Range("C" & i).Offset(0, 1).Value = Sheet2.Range("c" & j).Offset(0, -2).Value
Sheet6.Range("C" & i).Offset(0, 2).Value = Sheet2.Range("c" & j).Offset(0, 2).Value
Exit For
End If
Next j
Next i

Create a checkpoint in a foreach statement

I am writing a code that put an X in a cell depending on a offset cell value, for exemple if the offset cell has a value of 3, it will put an X in the cell and decrement the offset cell value, i want to save the location of that cell and start the next for each with it.
For Each Cell In plage
If (Cell.Offset(0, 1).Value <> 0) Then
If (Cell.Value <> "X") Then
Cell.Offset(0, 1).Value = Cell.Offset(0, 1).Value - 1
Cell.Value = "X"
Checkpoint = Cell.Address
Exit For
Else
Cell.Value = ""
GoTo NextStep
End If
Exit For
Else
Cell.Value = ""
End If
NextStep:
Next Cell
The problem i am having with the current code is it start the loop all over again while i want it to keep till the end of the lines, until all offset value are equal to 0.
Try the below (there are notes on the code). If you face difficulties let me know.
Option Explicit
Sub test()
'In this example we assume that the data you want to loop appear in Column A
Dim i As Long, Lastrow As Long
Dim Checkpoint As Variant
With ThisWorkbook.Worksheets("Sheet1") '<- Change sheet name if needed
Lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row '< -Fins the lastrow of the column you want to loop
For i = 2 To Lastrow ' < -Start looping from row 2 to Lastrow fo the column
If .Range("A" & i).Offset(0, 1).Value <> 0 Then '<- You are looping
If .Range("A" & i).Value <> "X" Then
.Range("A" & i).Offset(0, 1).Value = .Range("A" & i).Offset(0, 1).Value - 1
.Range("A" & i).Value = .Range("A" & i).Value & "X"
Checkpoint = .Range("A" & i).Address
Else
.Range("A" & i).Value = ""
End If
Else
.Range("A" & i).Value = ""
End If
Next i
End With
End Sub
Is plage a range?
If so, you could update it to start from the checkpoint and include all cells up to some lastCell for example.
Something like:
set plage=thisWorkbook.Worksheets("Your Worksheet").Range(checkpoint,lastCell)
That way the next For-Each should start from your checkpoint.
BTW if I understand correctly what you'e trying to do, I would suggest you replace cell.value="" with cell.clearContents

Macro filling wrong column with value?

Morning guys,
I have recently been tasked with being the person to update and monitor any VBA issues my currently company has, as the previous employee who was doing such has no left and there are no immediate plans to hire a replacement. Unfortunately my excel and VBA skills are rudimentary put politely, and youtube has only been able to help so much.
There is a macro used in one of the spreadsheets which checks and overwrites certain month end figures. This part of the macro runs fine, and when completed for each client an X should be input to column M (Labelled done) to signify this is done. The column N (labelled skip) is already filled with an X for those that should be skipped due to individual client technicalities.
The macro however appears to be filling in column N with the value x for when a client check is done. Have any of you ever encountered a similar issue with values being incorrectly assigned to the adjacent column?
Sub Values()
Application.ScreenUpdating = False
Dim EndRow As Integer
Dim i As Integer
Dim ValueDate As Date
Dim Cash As Double
Dim Value As Double
Dim APXRef As String
Dim d As Integer
Dim Overwrite As Boolean
Overwrite = Worksheets("Summary").Range("Y2").Value ' from checkboxes
EndRow = Range("J2").End(xlDown).Row
ValueDate = Range("P6").Value
If MsgBox("You are uploading with the following date: " & ValueDate & ", do
you want to continue?", vbYesNo) = vbNo Then Exit Sub
For i = 2 To EndRow
APXRef = Range("J" & i).Value
Value = Range("L" & i).Value
If Range("M" & i) = "" And Range("N" & i) = "" Then
Worksheets("Summary").Activate
r = Range("A:A").Find(APXRef).Row
Range("B" & r).Select
Call GoToClient
d = Range("A10").End(xlDown).Row
If Range("A" & d).Value < ValueDate Then
Range("A" & d + 1).Value = ValueDate
Range("B" & d + 1).Value = Value
Range("D" & d + 1).FormulaR1C1 = "=((RC[-2]/(R[-1]C[-2]+RC[-1]))-1)*100"
Range("E" & d + 1).FormulaR1C1 = "=((((R[-1]C)*(RC[-1]))/100)+R[-1]C)"
Range("H" & d + 1).Value = Range("H" & d).Value
'Save client
If Overwrite = True Then
Call SaveClient
End If
'Return to Flow Tab
Worksheets("Flows").Activate
Range("M" & i).Value = "x"
Else
'skip
Worksheets("Flows").Activate
Range("N" & i).Value = "x"
End If
End If
Application.StatusBar = TabRef & " " & Round(((i - 1) / (EndRow - 1)) *
100, 1) & "% Complete"
Next i
Application.StatusBar = "Value Update Complete"
End Sub

how to copy rows and columns to another worksheets on another workbooks

i have several workbooks which get copy from one master workbook. what i want to do is when i enter data into the master workbook, i want to copy it into another workbook based on product type which i get fromn Combobox1.Value. to be more clear, which workbooks i want to copy the data depends on the ComboBox1.value. ie if the ComboBox1.value equals to "Penofix" then i want to copy the data into the workbook "Penofix.xlsm". i have finish coding on master input on how to enter data into particular row based on some condition but facing problem to copy the data into another workbooks.
Private Sub CmdEnter_Click()
Dim CountRow As Long
Dim i As Long
Dim prod as string
Dim j As Long
Dim Ws As Worksheet
Dim Count1 as Long
'CountRow is number of row in master workbook
CountRow = Worksheets("Input").Range("B" & Rows.Count).End(xlUp).Row
'assign variable prod with combobox1 value
prod = ComboBox1.Value
'i=32 because my row start at 32
For i = 32 To countRow + 31
While ComboBox1.Value = Worksheets("Input").Cells(i, 2).Value
Rows(i).Select
Selection.Insert shift = xlDown
With Worksheets("Input")
'insert data into master workbook
.Range("B" & i) = ComboBox1.Text
.Range("C" & i) = TextBox1.Text
.Range("D" & i) = TextBox2.Text
.Range("E" & i) = TextBox3.Text
.Range("F" & i) = TextBox4.Text
.Range("G" & i) = TextBox5.Text
.Range("H" & i) = ComboBox2.Text
.Range("I" & i) = TextBox6.Text
.Range("J" & i) = TextBox7.Text
.Range("K" & i) = TextBox8.Text
End With
'activate other workbook to copy data,if prod = Penofix,the workbook will be "Penofix.xlsm"
workbooks(prod & ".xlsm").Activate
'count the number of row in workbooks(prod & ".xlsm").
' i specified cell (31,3) to calculate the number of row used
Count1 = Workbooks(prod & ".xlsm").Worksheets("Sheet1").Cells(31,3).Value
Count1 = Count1 + 31
'copy data into workbooks(prod & ".xlsm")
'THIS IS THE LINE WHICH ERROR
Workbooks(prod & ".xlsm").Worksheets("Input").Range(Cells(Count1, 2), Cells(Count1 , 11)).Value = Workbooks("Master.xlsm").Worksheets("Input").Range(Cells(i, 2), Cells(i, 11)).Value
If MsgBox("One record written to Input. Do you want to continue entering data?", vbYesNo)= vbYes Then
ComboBox1.Text = ""
TextBox1.Text = ""
TextBox2.Text = ""
TextBox3.Text = ""
TextBox4.Text = ""
TextBox5.Text = ""
ComboBox2.Text = ""
TextBox6.Text = ""
TextBox7.Text = ""
TextBox8.Text = ""
Else
Unload Me
End If
Exit Sub
Wend
Next
End Sub
i've try to replace
Workbooks(prod & ".xlsm").Worksheets("Input").Range(Cells(Count1, 2), Cells(Count1 , 11)).Value = Workbooks("Master.xlsm").Worksheets("Input").Range(Cells(i, 2), Cells(i, 11)).Value
with this
Workbooks(prod & ".xlsm").Worksheets("Input").Cells(Count1, 2).Value = Workbooks("Master.xlsm").Worksheets("Input").Cells(i, 2).Value
and yeah its work but it just for one singe cell only. so i think the error is on the syntax :
Range(Cells(Count1,2), Cells(Count1,11))
but i dont know how to make it to copy the entire row
Workbooks("Master.xlsm").Worksheets("Input").Range(cells(i,B).cells(i,K)).Value = _
Workbooks(prod & ".xlsm").).Worksheets("Sheet1").Range(Cells(CountRow, B). Cells(CountRow, K)).Value
This code will update the master workbook, I doubt you want to this. Also there is a syntax error with .). and then some.
I think this is what you need:
Dim sht1 As Worksheet, sht2 As Worksheet
Set sht1 = Workbooks(prod & ".xlsm").Worksheets("Sheet1")
Set sht2 = Workbooks("Master.xlsm").Worksheets("Input")
sht1.Range(sht1.Cells(CountRow, 2), sht1.Cells(CountRow, 11)).Value = _
sht2.Range(sht2.Cells(i, 2), sht2.Cells(i, 11)).Value
Imroved code: Using resize(<row>, <column>)
Workbooks(prod & ".xlsm").Worksheets("Sheet1").Cells(CountRow, 2).resize(, 11).Value = _
Workbooks("Master.xlsm").Worksheets("Input").Cells(i, 2).resize(, 11).Value
For some added info, the Cells(<Row>, <Column>) will only take integers in for either <Row> and <Column>. Hence the column B is represented as 2.

Resources