Excel VBA Listbox displays more times than expected - excel

My macro goes through all data rows on a specific sheet. Currently there are 6 rows. The first row is a negative number and the 2nd row is a positive number (debit and credit).
The macro reviews each row and displays a list box for the user to make a selection. Then it goes through the next row and does the same thing. I'm expecting the listbox to display 6 times, once for each row of data.
The problem I'm having is that the listbox is displaying 7 times. 3 times for the first pair or records and twice for the remaining pair of records. I can't figure out why the listbox is displaying the extra time.
Here is the code for the list box:
Private Sub ContinueButton_Click()
If IsNull(ListBox1.Value) Then
MsgBox " Please select the appropriate balance to continue. "
Exit Sub
Else
MyIndex = 0
MyIndex = ListBox1.ListIndex
MyIndex = MyIndex + 1
MyBal = ""
MyBal = APIARArray(MyIndex, 4)
Unload UserForm1
UserForm1.Hide
Sleep 750
End If
End Sub
Private Sub UserForm_Initialize()
UserForm1.Label1.Caption = "Please select the appropriate balance for Unit: " & vUnit
ListBox1.ColumnCount = 4
ListBox1.ColumnWidths = "50;50;75;50"
Dim i As Integer
With ListBox1
w = 1
i = 0
For w = 1 To UBound(APIARArray)
DoEvents
.AddItem
.List(i, 0) = APIARArray(w, 1)
.List(i, 1) = APIARArray(w, 2)
.List(i, 2) = APIARArray(w, 3)
.List(i, 3) = format(APIARArray(w, 4), "#,##0.00;[Red](#,##0.00)")
i = i + 1
Next
End With
UserForm1.Height = 215
UserForm1.Width = 348
ListBox1.SetFocus
End Sub
This is the code that calls the ListBox:
Sub LookForBalance()
Dim r As Integer
Dim APIUnit As String
r = 2
Do Until Len(Trim(Cells(r, 1))) + Len(Trim(Cells(r, 7))) + Len(Trim(Cells(r, 9))) + Len(Trim(Cells(r, 10))) + Len(Trim(Cells(r, 11))) = 0
DoEvents
If Trim(Cells(r, 27)) = "A199" Then
If Cells(r, 29) > 90 Then
APIUnit = ""
vUnit = ""
vUnit = Trim(Cells(r, 11))
If MyCntry = "A1" Then APIUnit = clsAPI.APIARSearch("WWW11", Trim(Cells(r, 11)))
If MyCntry = "A2" Then APIUnit = clsAPI.APIARSearch("WWW12", Trim(Cells(r, 11)))
If InStr(1, APIUnit, "ERROR") > 0 Then
Cells(r, 30) = "Unit Not Found"
Else
If UBound(APIARArray) > 1 Then
Load UserForm1
UserForm1.Show
Cells(r, 30) = MyBal
Else
Cells(r, 30) = APIARArray(1, 4)
End If
End If
End If
End If
r = r + 1
Loop
End Sub
There isn't much code here but I'm not sure what is going on. Any help or suggestions to resolve this issue would be greatly appreciated. Thanks in advance for your help.....

Related

How do I split the output of an excel report when collecting input with a user form and exporting to PDF?

I am trying to create a front-end form that can be filled out by a user, which will then populate a back-end spreadsheet the user cannot edit. This spreadsheet needs to follow a standard layout that I have already created, and the form will populate predetermined cells (or will create cells following the layout) based on user input from the form. I also need the form to be able to add/repeat questions, as well as duplicate sections in the spreadsheet based on user input requirements ("Do you need to add a section? [Yes/No]" //If [Yes], then duplicate section, repeat questions in form; if [No], then export data to spreadsheet, exit form). The spreadsheet layout consists of sections. The number of sections/cells per section required will vary from user to user, but the type of data will typically remain the same, and therefore should be able to choose the name of the field from a list of some sort (drop down?) However, the user may need to create a custom name for a field. I also need the form to be able to automatically adjust cell sizes based on the amount of text for that value. It is important that this form is printable, and does not separate sections from page to page. Furthermore, each "Notes" field will vary in size, and should be automatically resized to only show the existing text, plus one blank line for hand-written notes. I would also like the form to prompt the user to indicate whether a field is needed (some fields will be permanent, and the user will not be prompted about these fields). If the field is not needed, I need the form to exclude it from the final output.
I am open to suggestions on how to design this project differently than I have already (for example, using alternate programs/software/coding languages).
So far, however, I have created a user form in Excel that collects data and inputs it into a spreadsheet, which can then be exported to a PDF report using a set format/layout on another sheet of the workbook. The layout consists of a "Header" section and an "Item" section. In the form, the user can input a single job number and multiple item numbers, and when they export the report, the code prints the job number in the provided layout for the header, and then loops through the item numbers and copies and populates the item section for as many items as the user has provided. In the exported PDF, however, the item section gets split between pages, regardless of page orientation (landscape orientation is preferred). How do I prevent the "Item" section from being broken up between pages?
Option Explicit
Dim ctl As Control
Dim rCell As Range
Dim img As Picture
Dim newrow As ListRow
Dim tbl1 As ListObject
Dim msgValue As VbMsgBoxResult
Dim ary As Variant, aryx As Variant
Dim ws2 As Worksheet, ws1 As Worksheet
Dim s As String, FilePath As String, user As String, pFilename As String, part As String
Dim x As Long, sc As Long, j As Long, ctr As Long, rctr As Long, tbl1row As Long, r As Long, t As Long, items As Long, y As Long, ctrx As Long
Private Sub cmdCLEAR_Click()
MsgBox ("This action only clears the form NOT the record" & vbCrLf & "Ready for adding NEW entry."), vbOKOnly, "Clear Form "
CLEARFORM
Me.cmdADD.Enabled = True
Me.TextBox6.SetFocus
End Sub
Sub CLEARFORM()
For Each ctl In Me.Controls
Select Case TypeName(ctl)
Case "TextBox"
ctl.Text = ""
Case "ComboBox"
ctl.ListIndex = -1
ctl.Value = ""
End Select
Next ctl
Me.Image1.Picture = LoadPicture("") '*********clears picture******
End Sub
Private Sub cmdADD_Click()
For x = 1 To 35
If Controls("TextBox" & x).Text = "" Then
MsgBox "Data field missing", vbCritical, "Data missing"
Exit Sub
End If
Next x
msgValue = MsgBox("Do want to add another item?", vbYesNo + vbQuestion, "Next Item ?")
If msgValue = vbYes Then
SAVEDATANEXT
For x = 16 To 35
Me.Controls("TextBox" & x).Text = ""
Next x
Me.TextBox6.SetFocus
Exit Sub
End If
SAVEDATA
LOADLIST
LOADCOMBO1
End Sub
Sub SAVEDATANEXT()
Set newrow = tbl1.ListRows.Add
With newrow
For x = 1 To 35
.Range(x) = Me.Controls("TextBox" & x).Text '***************textbox35 contains picture filepath ***********
Next x
.Range(36) = tbl1.ListRows.Count '*********this is important row counter saves the need for search routines***********
End With
End Sub
Sub SAVEDATA()
Set newrow = tbl1.ListRows.Add
With newrow
For x = 1 To 35
.Range(x) = Me.Controls("TextBox" & x).Text '***************textbox35 contains picture filepath ***********
Next x
.Range(36) = tbl1.ListRows.Count '*********this is important row counter saves the need for search routines***********
End With
CLEARFORM
LOADLIST
End Sub
Sub LOADLIST()
Set ws2 = Sheet2
Set tbl1 = ws2.ListObjects("Table1")
With tbl1
If .DataBodyRange.Cells(1, 1) = vbNullString Then Exit Sub
ary = .DataBodyRange
End With
Me.ListBox1.List = ary
End Sub
Private Sub cmdPRINT_Click()
If Me.ComboBox1.Value = vbNullString Then
MsgBox "A PDF cannot be created because no Part # selected.", , "No Part# selected."
Exit Sub
End If
With Sheet3
.Range("A28:O10000").Clear
.Range("D2:D10").Value = ""
.Range("J2:J8").Value = ""
.Range("B17:N17").Value = ""
.Range("B19:N19").Value = ""
.Range("B21:N21").Value = ""
.Range("D23").Value = ""
For Each img In Sheet3.Pictures: img.Delete: Next img '**********clears pictures prior to building new PDF********
ctr = 28
For x = 1 To items - 2
.Range("A15:O26").Copy .Range("A" & ctr)
ctr = ctr + 13
Next x
For y = 2 To 8
.Range("D" & y).Value = Me.ListBox1.List(0, y - 2)
.Range("J" & y).Value = Me.ListBox1.List(0, y - 2 + 7)
.Range("D10").Value = Me.ListBox1.List(0, 14)
Next y
ctr = 0
ctrx = 0
For x = 1 To items - 1
.Cells(17 + ctr, 2).Value = Me.ListBox1.List(ctrx, 15)
.Cells(17 + ctr, 4).Value = Me.ListBox1.List(ctrx, 16)
.Cells(17 + ctr, 6).Value = Me.ListBox1.List(ctrx, 17)
.Cells(17 + ctr, 8).Value = Me.ListBox1.List(ctrx, 18)
.Cells(17 + ctr, 10).Value = Me.ListBox1.List(ctrx, 19)
.Cells(17 + ctr, 12).Value = Me.ListBox1.List(ctrx, 20)
.Cells(17 + ctr, 14).Value = Me.ListBox1.List(ctrx, 21)
.Cells(19 + ctr, 2).Value = Me.ListBox1.List(ctrx, 22)
.Cells(19 + ctr, 4).Value = Me.ListBox1.List(ctrx, 23)
.Cells(19 + ctr, 6).Value = Me.ListBox1.List(ctrx, 24)
.Cells(19 + ctr, 8).Value = Me.ListBox1.List(ctrx, 25)
.Cells(19 + ctr, 10).Value = Me.ListBox1.List(ctrx, 26)
.Cells(19 + ctr, 12).Value = Me.ListBox1.List(ctrx, 27)
.Cells(21 + ctr, 2).Value = Me.ListBox1.List(ctrx, 28)
.Cells(21 + ctr, 6).Value = Me.ListBox1.List(ctrx, 29)
.Cells(21 + ctr, 8).Value = Me.ListBox1.List(ctrx, 30)
.Cells(21 + ctr, 12).Value = Me.ListBox1.List(ctrx, 31)
.Cells(21 + ctr, 14).Value = Me.ListBox1.List(ctrx, 32)
.Cells(23 + ctr, 4).Value = Me.ListBox1.List(ctrx, 33)
'**************************************inserting picture into PDF loader*****************
pFilename = Me.ListBox1.List(ctrx, 34)
If pFilename = "" Then GoTo Err:
Set img = .Pictures.Insert(pFilename)
With img
.Left = Sheet3.Cells(23 + ctr, 14).Left
.Top = Sheet3.Cells(23 + ctr, 14).Top
.Width = 16
.Height = 44.25
.Placement = 1
.PrintObject = True
End With
Err:
'***************************************************************************************
ctrx = ctrx + 1
ctr = ctr + 13
Next x
End With
user = Environ("Username")
FilePath = "C:\Users\" & user & "\Desktop\"
ThisWorkbook.Worksheets("Sheet3").Select
part = Sheet3.Cells(2, 4)
Application.ScreenUpdating = True
'*****************set print area and orientaton********************
Application.PrintCommunication = False
With ActiveSheet.PageSetup
.Orientation = xlLandscape
.PrintArea = Sheet3.Range(Sheet3.Cells(1, 1), Sheet3.Cells(ctr, 15))
.Zoom = False
.FitToPagesTall = False
.FitToPagesWide = 1
INSERTBREAK
End With
Application.PrintCommunication = True
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=FilePath & "\Part# " & part, OpenAfterPublish:=False, IgnorePrintAreas:=False
'*********************************************************************
Application.ScreenUpdating = True
MsgBox "Data has been exported to PDF on Desktop."
With Sheet3
.Range("A28:O10000").Clear
.Range("D2:D10").Value = ""
.Range("J2:J8").Value = ""
.Range("B17:N17").Value = ""
.Range("B19:N19").Value = ""
.Range("B21:N21").Value = ""
.Range("D23").Value = ""
For Each img In Sheet3.Pictures: img.Delete: Next img '**********clears pictures ready to build new PDF********
End With
End Sub
'********************************open file dialog box to get picture location******************
Private Sub cmdGETPHOTO_Click()
On Error Resume Next
pFilename = Application.GetOpenFilename(FileFilter:="Jpg Files (*.jpg), *.jpg", Title:="SELECT TOOL PHOTO")
Me.Image1.Picture = LoadPicture(pFilename)
Me.TextBox35.Text = pFilename
End Sub
Private Sub CommandButton1_Click()
Unload Me
End Sub
Private Sub Frame1_Click()
End Sub
Private Sub Frame2_Click()
End Sub
Private Sub ListBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
If Me.ListBox1.ListIndex = -1 Then Exit Sub
If Me.ListBox1.ListIndex > -1 Then sc = Me.ListBox1.ListIndex
With Me.ListBox1
For x = 1 To 35
Me.Controls("TextBox" & x).Value = .List(sc, x - 1)
Next x
tbl1row = .List(sc, 35)
End With
On Error GoTo Err
Me.Image1.Picture = LoadPicture(Me.TextBox35.Text) 'retrieves picture file location************
Exit Sub
Err: Me.Image1.Picture = LoadPicture("")
End Sub
Private Sub cmdDELETE_Click()
If Me.ListBox1.ListIndex < 0 Then
MsgBox "No Record selected", , "Errors"
Exit Sub
End If
msgValue = MsgBox("ARE YOU CERTAIN YOU WISH TO REMOVE RECORD?", vbCritical + vbYesNo + vbDefaultButton2, "Remove Record")
If msgValue = vbNo Then
CLEARFORM
Exit Sub
End If
tbl1.ListRows(tbl1row).Delete
CLEARFORM
LOADLIST
LOADCOMBO1
MsgBox ("RECORD REMOVED"), vbOKOnly + vbInformation, "Record Removed"
End Sub
Private Sub cmdUPDATE_Click()
If Me.ListBox1.ListIndex < 0 Then
MsgBox "No Record selected", , "Errors"
Exit Sub
End If
With tbl1
For x = 1 To 35
.Range(tbl1row + 1, x) = Me.Controls("TextBox" & x).Text '*********textbox35 contains picture filepath **********
Next x
End With
CLEARFORM
LOADLIST
LOADCOMBO1
End Sub
Private Sub ComboBox1_Change()
With tbl1
r = .ListRows.Count
For t = r To 1 Step -1
.DataBodyRange.Cells(t, 36) = t '******loads range with rowctr prior to spliting with 'FILTER' ***********
Next t
End With
FILTER
items = Me.ListBox1.ListCount
End Sub
Sub FILTER()
ary = tbl1.DataBodyRange
rctr = 1
For j = 1 To UBound(ary)
If ary(j, 1) = Me.ComboBox1.Text Then
rctr = rctr + 1
End If
Next j
ReDim aryx(1 To rctr, 1 To 36)
ctr = 1
For j = 1 To UBound(ary)
If ary(j, 1) = Me.ComboBox1.Text Then
For x = 1 To 36
aryx(ctr, x) = ary(j, x)
Next x
ctr = ctr + 1
End If
Next j
Me.ListBox1.List = aryx
End Sub
Sub LOADCOMBO1()
Set ws2 = Sheet2
Set tbl1 = ws2.ListObjects("Table1")
With tbl1
If .DataBodyRange.Cells(1, 1) = vbNullString Then Exit Sub
ary = .DataBodyRange
End With
Me.ComboBox1.Clear
With CreateObject("Scripting.Dictionary")
For Each rCell In tbl1.ListColumns(1).DataBodyRange
If Not .Exists(rCell.Value) And rCell.Value <> vbNullString Then .Add rCell.Value, Nothing
Next rCell
Me.ComboBox1.List = .keys
.RemoveAll
End With
End Sub
Private Sub UserForm_Initialize()
Set ws2 = Sheet2
Set tbl1 = ws2.ListObjects("Table1")
Me.ListBox1.ColumnCount = 36
s = ""
For x = 1 To 36
s = s & 50 & ";"
Next x
Me.ListBox1.ColumnWidths = s
For x = 1 To 35
Me.Controls("Label" & x).Caption = tbl1.HeaderRowRange(x)
Next x
Me.cmdADD.Enabled = True
Me.TextBox35.Enabled = False
LOADLIST
LOADCOMBO1
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
'************ensures workbook is saved if accidently closed**************
If CloseMode = vbFormControlMenu Then
Cancel = False
ThisWorkbook.Save
Unload Me
End If
End Sub
I have tried using various forms of the PageBreak method. I have also tried setting the page layout in various ways, but nothing has worked. I even tried grouping the cells in the "Item" section. I am at a total loss.

Editing rows works for one listbox but not another

I have a form with two different listboxes. One for downtime data and one for production data. I can add new data and delete data via both listboxes. I can edit a selected row as well. The problem I'm running into is that after I edit and update a row for the production listbox and then enter in new data for new row it keeps putting that data in the last row I edited. If I don't edit a row then anytime I add new data it automatically goes to the next row. This doesn't happen with the downtime section, only the production section. With the downtime section everything works as it should. Attached is the workbook. Any help is greatly appreciated.
This is the code to update the listbox with what was entered into the text boxes above the listbox.
Sub Prod_Submit()
Dim sh As Worksheet
Dim iRow As Long
Set sh = ThisWorkbook.Sheets("ADHData")
If MainForm.txtRowNumberProd.Value = "" Then
iRow = [Counta(ADHData!A:A)] + 1
Else
iRow = MainForm.txtRowNumberProd.Value
End If
With sh
.Cells(iRow, 1) = MainForm.OrderA.Value
.Cells(iRow, 2) = MainForm.StockA.Value
.Cells(iRow, 3) = MainForm.FaceA.Value
.Cells(iRow, 4) = MainForm.LinerA.Value
.Cells(iRow, 5) = MainForm.WidthA.Value
.Cells(iRow, 6) = MainForm.PrevContA.Value
.Cells(iRow, 7) = MainForm.ContA.Value
.Cells(iRow, 8) = MainForm.PrevGoodA.Value
.Cells(iRow, 9) = MainForm.GoodA.Value
End With
End Sub
This is my code for selecting the row that needs to be edited
Private Sub CommandButton2_Click()
If Select_Prod = 0 Then
MsgBox "No row is selected.", vbOKOnly + vbInformation, "Edit"
Exit Sub
End If
MainForm.txtRowNumberProd.Value = Select_Prod + 1
MainForm.OrderA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 0)
MainForm.StockA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 1)
MainForm.FaceA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 2)
MainForm.LinerA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 3)
MainForm.WidthA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 4)
MainForm.PrevContA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 5)
MainForm.ContA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 6)
MainForm.PrevGoodA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 7)
MainForm.GoodA.Value = MainForm.Production_TableA.List(MainForm.Production_TableA.ListIndex, 8)
MsgBox "Please make the required changes and update the new production data.", vbOKOnly + vbInformation, "Edit"
End Sub
And this is my Select_Prod Code
Function Select_Prod() As Long
Dim i As Long
Select_Prod = 0
For i = 0 To MainForm.Production_TableA.ListCount - 1
If MainForm.Production_TableA.Selected(i) = True Then
Select_Prod = i + 1
Exit For
End If
Next i
End Function
And my code to reset the textboxes
Sub Prod_Reset()
Dim iRow As Long
iRow = [Counta(ADHData!A:A)] + 1 ' idetifying the last row
With MainForm
MainForm.OrderA.Value = ""
MainForm.StockA.Value = ""
MainForm.FaceA.Value = ""
MainForm.LinerA.Value = ""
MainForm.WidthA.Value = ""
MainForm.PrevContA.Value = ""
MainForm.ContA.Value = ""
MainForm.PrevGoodA.Value = ""
MainForm.GoodA.Value = ""
.Production_TableA.ColumnCount = 9
.Production_TableA.ColumnHeads = True
.Production_TableA.ColumnWidths = "55,55,70,71,50,106,77,69,42"
If iRow > 1 Then
.Production_TableA.RowSource = "ADHData!A2:J" & iRow
Else
.Production_TableA.RowSource = "ADHData!A2:J21"
End If
End With
End Sub

Excel-VBA update userform listbox based on existing list

I have a useform with multicolumn listbox which lists items and its quantity. The intent is to be able to dynamically update the quantity by adding or deducting from a textbox input. Below is my current code roughly to realize this. So far it is not working with invalid qualifier error for selected(i). would appreciate any guidance on this
Private Sub CB_AddOrder_Click()
Dim j, k, qty As Integer
Dim i As Variant
qty = TB_Qty.Value
If qty = 0 Then
Exit Sub
End If
j = LB_Order.ListCount - 1
Debug.Print j
If j < 0 Then
j = 0
End If
'Iterate to check if selected menu already existed in ordered list
For i = 0 To LB_Menu.ListCount - 1
If LB_Menu.Selected(i) = True Then
Debug.Print Selected(i)
For k = 0 To j
If LB_Menu.Selected(i).List(i, 0) = LB_Order.List(k, 0) Then
LB_Order.List(k, 3) = LB_Order.List(k, 3).Value + qty
Exit Sub
End If
Next k
With LB_Order
.ColumnCount = 5
.ColumnWidths = "120;60;60;60;60"
.AddItem
.List(j, 0) = LB_Menu.List(i, 0)
.List(j, 1) = LB_Menu.List(i, 1)
.List(j, 2) = LB_Menu.List(i, 2)
.List(j, 3) = qty
.List(j, 4) = Format(qty * LB_Menu.List(i, 2), "0.00")
End With
End If
Next i
End sub
The confusion you're having relates from the difference in which listbox item(s) are selected and the value of those selected item(s). So when you check for Selected:
Dim i As Long
For i = 0 To LB_Menu.ListCount - 1
If LB_Menu.Selected(i) Then
Debug.Print "Menu selected (" & i & ") = " & LB_Menu.List(i, 0)
End If
Next i
Once you determine which index (i in this case) is selected, you refer to the value by using the index into the List.
The Object Required error you received is because your statement
LB_Order.List(k, 3) = LB_Order.List(k, 3).Value + qty
is using .Value for the list item. This item is a value, not an object.
Here is your sub rewritten as an example. Notice that I'm using single-character variables as loop indexes (which is good), but not as a meaningful value. I renamed other variables in (a hopefully) meaningful way to make your code a little more self-documenting.
Option Explicit
Private Sub CB_AddOrder_Click()
Dim additionalQty As Long
additionalQty = TB_Qty.Value
If additionalQty = 0 Then
Exit Sub
End If
Dim countOfOrderItems As Long
countOfOrderItems = LB_Order.ListCount - 1
If countOfOrderItems < 0 Then
countOfOrderItems = 0
End If
'Iterate to check if selected menu already existed in ordered list
Dim i As Long
For i = 0 To LB_Menu.ListCount - 1
If LB_Menu.Selected(i) Then
Debug.Print "Menu selected (" & i & ") = " & LB_Menu.List(i, 0)
'--- find the matching item and increase the quantity
Dim k As Long
For k = 0 To countOfOrderItems
If LB_Menu.List(i) = LB_Order.List(k, 0) Then
LB_Order.List(k, 3) = LB_Order.List(k, 3) + additionalQty
Exit Sub
End If
Next k
'--- append the new item from the Menu to the Order
With LB_Order
.ColumnCount = 5
.ColumnWidths = "120;60;60;60;60"
.AddItem
.List(countOfOrderItems, 0) = LB_Menu.List(i, 0)
.List(countOfOrderItems, 1) = LB_Menu.List(i, 1)
.List(countOfOrderItems, 2) = LB_Menu.List(i, 2)
.List(countOfOrderItems, 3) = additionalQty
.List(countOfOrderItems, 4) = Format(additionalQty * LB_Menu.List(i, 2), "0.00")
End With
End If
Next i
End Sub
By the way, make sure all of the columns in your listboxes are initialized with values if you will add/subtract number values. If they are just Null, you'll get a Could not set the List property error.

How do I code my userform to insert the specified number of rows beneath the selected cell?

I have a userform that I've created that first asks how many rows I would like to insert. The next part of the userform asks what values I would like in columns 1 and 32 of each newly created row (I've set it up so that a maximum of 6 new rows can be created at one time). My data has 45 columns, and the only data that I want to change in the newly created rows is the data in the two columns i said earlier (1 and 32). I want the data from all the other columns from the original row to be copied down into each new row. My problem is that I can't seem to figure out how to write a code that will do this the way I want it. To provide an example, if I respond to the userform that I want to add 3 rows below the currently active cell, it will then ask me what values i want to enter for columns 1 and 32 for each of these new rows. So I would enter something like this:
First New Row
Column 1: 8/17/2019
Column 32: 400
Second New Row
Column 1: 8/10/2019
Column 32: 500
Third New Row
Column 1: 8/3/2019
Column 32: 600
I've tried many different codes but I've only really figured out how to write it so that it inserts one row below the active cell and its completely blank, I don't know how to program it so that it enters he values I selected for columns 1 and 32 and copies all other data down from the original row. I've figured out the code for the clear and cancel button on my userform already, I am now only concerned with writing this code for the "OK" button.
Private Sub CancelButton_Click()
Unload Me
End Sub
Private Sub ClearButton_Click()
Call UserForm_Initialize
End Sub
Private Sub OKButton_Click()
Dim lRow As Long
Dim lRsp As Long
On Error Resume Next
lRow = Selection.Row()
lRsp = MsgBox("Insert New row above " & lRow & "?", _
vbQuestion + vbYesNo)
If lRsp <> vbYes Then Exit Sub
Rows(lRow).Select
Selection.Copy
Rows(lRow + 1).Select
Selection.Insert Shift:=xlDown
Application.CutCopyMode = False
Rows(lRow).PasteSpecial Paste:=xlPasteFormulas, Operation:=xlNone
End Sub
Private Sub UserForm_Initialize()
AddRowsTextBox.Value = ""
Date1TextBox.Value = ""
Date2TextBox.Value = ""
Date3TextBox.Value = ""
Date4TextBox.Value = ""
Date5TextBox.Value = ""
Date6TextBox.Value = ""
Qty1TextBox.Value = ""
Qty2TextBox.Value = ""
Qty3TextBox.Value = ""
Qty4TextBox.Value = ""
Qty5TextBox.Value = ""
Qty6TextBox.Value = ""
End Sub
what i understand from your requirement, I would have add one more spin button on the form to make it user friendly. It may look like this.
User form Code may please be modified according to control names in your form
Option Explicit
Public Bal As Double, XQnty As Double, LargeOrder As Double, Sm As Double
Private Sub CommandButton1_Click()
Dim lRow As Long
Dim lRsp As Long
lRow = ActiveCell.Row()
lRsp = MsgBox("Insert New row Below " & lRow & "?", vbQuestion + vbYesNo)
If lRsp <> vbYes Then Exit Sub
Dim Ws As Worksheet
Dim R As Long, i As Integer, RowtoAdd As Integer
Set Ws = ThisWorkbook.ActiveSheet
RowtoAdd = Me.SpinButton1.Value
R = ActiveCell.Row
With Ws
.Cells(R, 32).Value = LargeOrder
For i = 1 To RowtoAdd
.Cells(R + 1, 1).EntireRow.Insert Shift:=xlDown
.Cells(R, 1).EntireRow.Copy Destination:=.Cells(R + 1, 1)
.Cells(R + 1, 1).Value = Me.Controls("TextBox" & i).Value
.Cells(R + 1, 32).Value = Me.Controls("TextBox" & 7 + i).Value
R = R + 1
Next i
End With
Unload Me
End Sub
Private Sub CommandButton2_Click()
Unload Me
End Sub
Private Sub SpinButton1_Change()
Dim x As Integer, i As Integer, Y As Double
Me.TextBox7.Value = Me.SpinButton1.Value
x = Me.SpinButton1.Value
Sm = 0
For i = 1 To 6
Me.Controls("TextBox" & i).BackColor = IIf(i <= x, RGB(255, 100, 100), RGB(255, 2550, 255))
Me.Controls("TextBox" & i + 7).Value = IIf(i <= x, Int(Bal / x), 0)
Sm = Sm + IIf(i <= x, Int(Bal / x), 0)
Next
If Sm <> Bal Then
Me.TextBox8.Value = Int(Bal / x) + Bal - Sm
End If
ManualBal
End Sub
Private Sub TB_LO_Change()
LargeOrder = Val(Me.TB_LO.Value)
Bal = XQnty - LargeOrder
ManualBal
End Sub
Private Sub UserForm_Initialize()
Dim i As Integer, dx As Variant
Me.SpinButton1.Value = 1
Me.TextBox7.Value = 1
Me.TextBox1.BackColor = RGB(255, 100, 100)
dx = ThisWorkbook.ActiveSheet.Cells(ActiveCell.Row, 1).Value
XQnty = ThisWorkbook.ActiveSheet.Cells(ActiveCell.Row, 32).Value
LargeOrder = 575
Bal = XQnty - LargeOrder
Sm = 0
If IsDate(dx) = False Then dx = Now()
For i = 1 To 6
Me.Controls("TextBox" & i).Value = Format(dx - i * 7, "mm-dd-yyyy")
Sm = Sm + Int(Bal / 6)
Me.Controls("TextBox" & i + 7).Value = Int(Bal / 6)
Next
If Sm <> Bal Then
Me.TextBox8.Value = Int(Bal / 6) + Bal - Sm
End If
Me.TB_LO = LargeOrder
Me.TB_Bal = 0
End Sub
Private Sub ManualBal()
Dim x As Integer, i As Integer
x = Me.SpinButton1.Value
Bal = XQnty - LargeOrder
Sm = 0
For i = 1 To 6 ' Or may use 6 insted of X
Sm = Sm + Val(Me.Controls("TextBox" & i + 7).Value)
Next
Me.TB_Bal.Value = Bal - Sm
End Sub
Private Sub TextBox8_Exit(ByVal Cancel As MSForms.ReturnBoolean)
ManualBal
End Sub
Private Sub TextBox9_Exit(ByVal Cancel As MSForms.ReturnBoolean)
ManualBal
End Sub
Private Sub TextBox10_Exit(ByVal Cancel As MSForms.ReturnBoolean)
ManualBal
End Sub
Private Sub TextBox11_Exit(ByVal Cancel As MSForms.ReturnBoolean)
ManualBal
End Sub
Private Sub TextBox12_Exit(ByVal Cancel As MSForms.ReturnBoolean)
ManualBal
End Sub
Private Sub TextBox13_Exit(ByVal Cancel As MSForms.ReturnBoolean)
ManualBal
End Sub
Here Text Box 1 to 6 for dates, 7 for Spin Button values and Text Box 8 to 13 for quantity. May please either modify code according to control names Or modify Control names according to code.
Edit: Two new Text Box added named TB_BAL to show when entering values in manually in Quantity text boxes (balance calculated only at exit event of text boxes) and TB_LO to change LargeOrder during run.

ListBox Control: First Row Disappears

REPOST from my question yesterday.
Complete code below:
I think the problem is at .Column = MyArray where I send the values into the Listbox thru .column instead of .additem. But i can't figure out how to .additem an array.
Option Explicit
Dim MyArray As Variant
Dim n As Integer
Private Sub UserForm_initialize()
n = 0
End Sub
Private Sub FBcv_aDD_Click()
ReDim MyArray(4, n)
Dim i As Long
'============================================
If ListBox_FB.ListIndex = True Then
MyArray(0, n) = "Cavity Fixing Block"
MyArray(1, n) = FBcv_L.Value & " x " & FBcv_W.Value & " x " & FBcv_T.Value
If FBcv_Qty <= 1 Then
MyArray(2, n) = FBcv_Qty.Value & "pc."
ElseIf FBcv_Qty > 1 Then
MyArray(2, n) = FBcv_Qty.Value & "pcs."
End If
MyArray(3, n) = FBmat.Value
MyArray(4, n) = FBcv_uPRICE.Value
n = n + 1
End If
'============================================
With ListBox_FB
For i = 0 To ListBox_FB.ListCount - 1
If ListBox_FB.ListIndex = False Then
.AddItem ListBox_FB.List(i, 0)
ListBox_FB.List(ListBox_FB.ListCount - 1, 1) = ListBox_FB.List(i, 1)
ListBox_FB.List(ListBox_FB.ListCount - 1, 2) = ListBox_FB.List(i, 2)
ListBox_FB.List(ListBox_FB.ListCount - 1, 3) = ListBox_FB.List(i, 3)
ListBox_FB.List(ListBox_FB.ListCount - 1, 4) = ListBox_FB.List(i, 4)
End If
Next i
.ColumnCount = 5
.TextAlign = 1
.Column = MyArray
End With
End Sub
Sorry I had to repost this, i messed up with my first question.
Can anyone help me sort this out?
Any help is highly appreciated. Thanks in advanCce.

Resources