Unload form after printing in Excel - excel

In frmClothingPricer, when cmdPrint is pressed, frmPrint activates and is printed however many times asked for. I don't want 10+ frmPrint "active". How can I close frmPrint after each print loop? I have tried it on frmPrint "Unload Me" but that doesn't unload it either. ?? what am I missing?
Routine for printing
If Len(HowMany) = 0 Then
End
Else
Do Until i = HowMany
frmPrint.Show 'prints form on activation
i = i + 1
Unload frmPrint 'this isn't working = several forms are open
Loop
End If
frmPrint code
Private Sub UserForm_Initialize()
PrintMe
End Sub
Private Sub PrintMe()
lblPrintMonthCode.Caption = frmClothingPricer.MonthCode
lblPrintPricer.Caption = frmClothingPricer.Pricer
lblPrintCost.Caption = (frmClothingPricer.Cost * 100)
lblPrintDescription.Caption = frmClothingPricer.Description
lblPrintPrice.Caption = frmClothingPricer.Price
lblPrintItemNumber = frmClothingPricer.ItemNumber
frmPrint.PrintForm
'tried unload.me here with same results
End Sub

I solved it by keeping all the code except labels on the original form. The latest errors revolved around variables I messed up switching around. It now works perfectly (below):
form1
Public Price As Double
Public Percent As Double
Public Cost As Currency
Public Description As String
Public MonthCode As Integer
Public Pricer As String
Public ItemNumber As Double
Private Sub UserForm_Initialize()
Pricer = InputBox("Enter Your Pricer Number", vbOKOnly, "")
If Len(Pricer) = 0 Then 'Checking if Length of name is 0 characters
End
Else
End If
End Sub
Private Sub cmdSearch_Click()
Dim Response As Long
Dim NotFound As Integer
Dim arr As Variant
Dim i As Long
Dim str1 As String, str2 As String, str3 As String
lbxCost.BackColor = &H80000005
lbxCost.Locked = False
NotFound = 0
ActiveWorkbook.Sheets("Items").Activate
Response = Val("0" & Replace(txtItemNumber.Text, "-", ""))
ItemNumber = Response
If Response <> False Then
With ActiveSheet
arr = .Range("A2:D" & .Cells(.Rows.Count, "A").End(xlUp).Row)
End With
For i = 1 To UBound(arr)
If arr(i, 1) = Response Then
str1 = IIf(str1 = "", arr(i, 2), str1 & "|" & arr(i, 2))
str2 = IIf(str2 = "", arr(i, 3), str2 & "|" & arr(i, 3))
str3 = IIf(str3 = "", arr(i, 4), str3 & "|" & arr(i, 4))
End If
Next
If str1 = "" Then
MsgBox "Item Number Not Found!", vbExclamation
NotFound = 1
txtItemNumber.Text = ""
txtItemNumber.SetFocus
Else
Frame1.Visible = True
lbxDescription.List = Split(str1, "|")
lbxCost.List = Split(str2, "|")
ListBox3.List = Split(str3, "|")
End If
End If
lbxCost.ListIndex = 0
End Sub
Private Sub lbxCost_Click()
Frame2.Visible = True
End Sub
Private Sub lbxPercent_Click()
Frame3.Visible = True
lbxCost.BackColor = &H80000004
lbxCost.Locked = True
For x = 0 To lbxCost.ListCount - 1
If lbxCost.Selected(x) = True Then
Cost = lbxCost.List(x)
Description = lbxDescription.List(x)
End If
Next x
For y = 0 To lbxPercent.ListCount - 1
If lbxPercent.Selected(y) = True Then
Percent = lbxPercent.List(y)
End If
Next y
lblPrice.Caption = (Round(Cost * (1 + (Percent / 100)), 0)) - 0.01
Price = lblPrice.Caption
lblItemNumber.Caption = txtItemNumber.Text
lblDescription.Caption = Description
MonthCode = (Year(Now)) + (Month(Now)) - 1765
lblMonthCode.Caption = MonthCode
lblPricer.Caption = Pricer
cmdPrint.SetFocus
End Sub
Private Sub cmdPrint_Click()
Dim i As Integer
Dim Howmany As Double
Load frmPopup
Howmany = Val(txtQuantity.Text)
i = 1
Do Until i > Howmany
frmPopup.PrintForm
i = i + 1
Loop
lbxPercent.ListIndex = -1
Frame1.Visible = False
Frame2.Visible = False
Frame3.Visible = False
txtItemNumber.Text = ""
txtItemNumber.SetFocus
Unload frmPopup
End Sub
form2
Private Sub UserForm_Initialize()
lblPrintMonthCode.Caption = frmClothingPricer.MonthCode
lblPrintPricer.Caption = frmClothingPricer.Pricer
lblPrintCost.Caption = (frmClothingPricer.Cost * 100)
lblPrintDescription.Caption = frmClothingPricer.Description
lblPrintPrice.Caption = frmClothingPricer.Price
lblPrintItemNumber = frmClothingPricer.ItemNumber
End Sub

Related

How to compare two values in VBA when a value is bound to vbNewLine in Excel or Access

This is about the structure of a calendar and since I already have too many functions built in, I am not allowed to change the block with vbNewLine , so I need to find a way to solve the problem at this one point:
A function should compare two values and trigger an action in case of a match.
The value myArray(i, 2) ist the Day-Number:
Private Sub InitVariables()
intMonth = Me.cboMonth
intYear = Me.cboYear
lngFirstDayOfMonth = CLng(DateSerial(intYear, intMonth, 1))
intFirstWeekday = getFirstWeekday(lngFirstDayOfMonth)
intDaysInMonth = getDaysInMonth(intMonth, intYear)
End Sub
Private Sub InitArray()
Dim i As Integer
ReDim myArray(0 To 41, 0 To 2)
For i = 0 To 41
myArray(i, 0) = lngFirstDayOfMonth - intFirstWeekday + 1 + i
If Month(myArray(i, 0)) = intMonth Then
myArray(i, 1) = True
myArray(i, 2) = Day(myArray(i, 0))
Else
myArray(i, 1) = False
End If
Next i
End Sub
Private Sub LoadArray()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim rsFiltered As DAO.Recordset
Dim strsql As String
Dim i As Integer
Dim OrgTime As Date
Dim MyStrTime As String
On Error Resume Next
strsql = "SELECT * from qrytblImVst;"
Set db = CurrentDb
Set rs = db.OpenRecordset(strsql)
If Not rs.BOF And Not rs.EOF Then
For i = LBound(myArray) To UBound(myArray)
If myArray(i, 1) Then
rs.Filter = "[vDate]=" & myArray(i, 0)
Set rsFiltered = rs.OpenRecordset
Do While (Not rsFiltered.EOF)
OrgTime = rsFiltered!vZeit
MyStrTime = Format(OrgTime, "hh:mm")
myArray(i, 2) = myArray(i, 2) & vbNewLine _
& "<div><font color=red> " + MyStrTime + " </div>"
End If
rsFiltered.MoveNext
Loop
End If
Next i
End If
rsFiltered.Close
rs.Close
Set rsFiltered = Nothing
Set rs = Nothing
Set db = Nothing
End Sub
Private Sub PrintArray()
'On Error Resume Next
Dim strCtlName As Variant
Dim strCtlName1 As Variant
Dim i As Integer
Dim lngBlack As Long
Dim lngWhite As Long
lngBlack = RGB(36, 39, 50)
lngWhite = RGB(166, 166, 166)
For i = LBound(myArray) To UBound(myArray)
strCtlName = "TXT" & CStr(i + 1)
Controls(strCtlName).Tag = i
Controls(strCtlName) = ""
Controls(strCtlName) = myArray(i, 2)
If IsNull(Controls(strCtlName)) Then
Controls(strCtlName).Visible = False
Else
Controls(strCtlName).Visible = True
End If
If CStr(Me.cboMonth) = CStr(Month(Date)) And CStr(Me.cboYear) = CStr(Year(Date)) And Len(myArray(i, 2)) <> 0 Then
If Split(myArray(i, 2), vbNewLine)(0) = CStr(Day(Date)) Then
Controls(strCtlName).BorderColor = lngRed
Controls(strCtlName).BorderWidth = 2
End If
Else
Controls(strCtlName).BorderColor = lngWhite
Controls(strCtlName).BorderWidth = 1
End If
strCtlName = "CAL" & CStr(i + 1)
Controls(strCtlName).Tag = i
Controls(strCtlName) = ""
If InStr(myArray(i, 2), "div") Then
Controls(strCtlName) = Left(myArray(i, 2), 2)
Else
Controls(strCtlName) = myArray(i, 2)
End If
If IsNull(Controls(strCtlName)) Then
Controls(strCtlName).Visible = False
Else
Controls(strCtlName).Visible = True
End If
Next i
End Sub
This is how the comparison looks:
If Left(myArray(i, 2), 2) = CStr(Day(Date)) Then
Controls(strCtlName).BorderColor = lngRed
Controls(strCtlName).BorderWidth = 2
End If
I always get a FALSE as a result because vbNewLine changes the day number value in such a way that there is no match.
To check what is causing the problem I added "//" and it looks like this
msgbox Left(myArray(i, 2), 2) & "//"
The result is:
5
//
How can I solve this problem, for all calendar days? Thanks!
Your comparison is looking at the first two characters of the stored value. When the day number is less than 10, the second character will be vbNewLine because the day number is only one digit.
Instead of using Left to capture a fixed number of characters, you can use Split to capture everything to the left of vbNewLine.
If Split(myArray(i, 2), vbNewLine)(0) = CStr(Day(Date)) Then
Controls(strCtlName).BorderColor = lngRed
Controls(strCtlName).BorderWidth = 2
End If
Split will return Error (9) when myArray(i,2) doesn't have a value. You'll need to introduce a check for that case:
If Len(myArray(i,2)) <> 0 Then
If Split(myArray(i, 2), vbNewLine)(0) = CStr(Day(Date)) Then
Controls(strCtlName).BorderColor = lngRed
Controls(strCtlName).BorderWidth = 2
End If
End If

excel vba sorting int values on list view

i need to sort my values by their int values for example
1
2
3
10
1000
but my code works like string like this
1
10
100
2
3
here is my sorting code for EXCEL VBA :
Private Sub lstview1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
With lstview1
.SortKey = ColumnHeader.Index - 1
If .SortOrder = lvwAscending Then
.SortOrder = lvwDescending
Else
.SortOrder = lvwAscending
End If
.Sorted = True
End With
End Sub
how can i fix this for excel vba
The Listview sorts alphabetically and that is one of it's limitations. Here is a quick example that I created for you to sort numeric data.
Code
Option Explicit
Dim i As Long
Private Sub UserForm_Initialize()
With ListView1
.View = lvwReport
.ColumnHeaders.Add , , "Number", 50
.ColumnHeaders.Add , , "Fruit", 50
For i = 1000 To 1 Step -1
.ListItems.Add(, , i).SubItems(1) = "Fruit" & i
Next
End With
End Sub
Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
With ListView1
If ColumnHeader.Index = 1 Then
SortDataWithNumbers
Else
.Sorted = True
End If
End With
End Sub
Sub SortDataWithNumbers()
Dim sTemp As String * 10
Dim lvCount As Long
With ListView1
lvCount = .ListItems.Count
For i = 1 To lvCount
sTemp = vbNullString
If .SortKey Then
'RSet - right align a string within a string variable.
RSet sTemp = .ListItems(i).SubItems(.SortKey)
.ListItems(i).SubItems(.SortKey) = sTemp
Else
RSet sTemp = .ListItems(i)
.ListItems(i).Text = sTemp
End If
Next
.Sorted = True
For i = 1 To lvCount
If .SortKey Then
.ListItems(i).SubItems(.SortKey) = _
LTrim$(.ListItems(i).SubItems(.SortKey))
Else
.ListItems(i).Text = LTrim$(.ListItems(i))
End If
Next
End With
End Sub
In Action
Siddharth Rout code works great, but if you want to be able to sort all columns and some of them are numeric, you can use ColumnHeader.Index, and with the following code (source and credits: https://www.tek-tips.com/viewthread.cfm?qid=578008):
Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
With ListView1
.Sorted = False
If .SortKey <> ColumnHeader.Index - 1 Then
.SortKey = ColumnHeader.Index - 1
Else
.SortOrder = 1 - .SortOrder
End If
'In the following line you specify the columns with numeric values
If ColumnHeader.Index = 1 Or ColumnHeader.Index = 7 Then
Dim S As String * 10, N As Integer
'justify the text using padding spaces
For N = 1 To .ListItems.Count
S = vbNullString
If .SortKey Then
RSet S = .ListItems(N).SubItems(.SortKey)
.ListItems(N).SubItems(.SortKey) = S
Else
RSet S = .ListItems(N)
.ListItems(N).Text = S
End If
Next
'sort column using "justified" text
.Sorted = True
'trim spaces from the text
For N = 1 To .ListItems.Count
If .SortKey Then
.ListItems(N).SubItems(.SortKey) = _
LTrim$(.ListItems(N).SubItems(.SortKey))
Else
.ListItems(N).Text = LTrim$(.ListItems(N))
End If
Next
Else
.Sorted = True
End If
End With
End Sub

Creating a loop within a UserForm

this is a continuation of my previous question...
I'm trying to create a user form that will go through a list on a worksheet (TESTER). The form should display the first row of data from the list. User will also be able to select one of two options Active or ITW. Finally, the user is free to add additional comments.
This is where I'm running into trouble, once the user clicks Add, the values from the form should populate the next blank row in a separate sheet (pasteHere). I have no issues with the form displaying the next line of data on the list, but I don't know how to create a loop that will allow me to find the next blank row after clicking the add button. At the moment, I've only initialized j as 1. And every time I click add, it will paste on the first row in the pasteHere worksheet.
Sub addBtn_Click()
Application.ScreenUpdating = False
Dim pasteSheet As Worksheet
Dim j As Long
j = 1 'how can I loop this part
Set pasteSheet = Application.Worksheets("pasteHere")
pasteSheet.Cells(j, j) = ric
pasteSheet.Cells(j, j + 2) = name
pasteSheet.Cells(j, j + 4) = valueUSD
pasteSheet.Cells(j + 1, j) = dstr
i = i + 1
j = j + 2
UserForm1_Initialize
End Sub
Would appreciate any help here. Full code below:
Public valueUSD, name, ric, dstr, sitchStr, pStr As String
Public i, lRow As Long
Sub UserForm1_Initialize()
If Worksheets("pasteHere").Range("A1") = "" Then
i = 2
End If
activeCheck.Value = False
itwCheck.Value = False
TextBox2.Value = ""
ric = Worksheets("Tester").Range("H" & i)
name = Worksheets("Tester").Range("B" & i)
valueUSD = Worksheets("Tester").Range("C" & i)
sitchStr = ""
dstr = ""
pStr = ric & " " & name & " " & valueUSD & " "
UserForm1.Label1.Caption = pStr
End Sub
Sub activeCheck_Change()
If activeCheck.Value = True Then
sitchStr = sitchStr + activeCheck.Caption
Else
sitchStr = ""
End If
End Sub
Sub itwCheck_Change()
If activeCheck.Value = False And itwCheck.Value = True Then
sitchStr = sitchStr + itwCheck.Caption
ElseIf activeCheck.Value = True And itwCheck.Value = True Then
MsgBox ("You can only be active OR ITW")
End If
End Sub
Sub TextBox2_Change()
dstr = sitchStr & ", " & TextBox2.Value
End Sub
Sub addBtn_Click()
Application.ScreenUpdating = False
Dim pasteSheet As Worksheet
Dim j As Long
j = 1 'how can I loop this part
Set pasteSheet = Application.Worksheets("pasteHere")
pasteSheet.Cells(j, j) = ric
pasteSheet.Cells(j, j + 2) = name
pasteSheet.Cells(j, j + 4) = valueUSD
pasteSheet.Cells(j + 1, j) = dstr
i = i + 1
j = j + 2
UserForm1_Initialize
End Sub
Sub skipBtn_Click()
i = i + 1
UserForm1_Initialize
End Sub
Sub exitBtn_Click()
Unload Me
End Sub

Could not get column property.Invalid argument

Could net get column property. invalid argument
How not to populate the listbox and put all the data in textbox instead? Is there anyway to loop this?
Private Sub ListBox1_Click()
Dim say, LastRow As Long
TextBox1 = ListBox1.Column(0)
TextBox2 = ListBox1.Column(1)
TextBox3 = ListBox1.Column(2)
TextBox4 = ListBox1.Column(3)
TextBox5 = ListBox1.Column(4)
TextBox6 = ListBox1.Column(5)
TextBox7 = ListBox1.Column(6)
TextBox8 = ListBox1.Column(7)
TextBox11 = ListBox1.Column(8)
TextBox12 = ListBox1.Column(9)
TextBox13 = ListBox1.Column(10)
TextBox14 = ListBox1.Column(11)
TextBox15 = ListBox1.Column(12)
TextBox16 = ListBox1.Column(13)
TextBox17 = ListBox1.Column(14)
TextBox18 = ListBox1.Column(15)
TextBox19 = ListBox1.Column(16)
TextBox20 = ListBox1.Column(17)
TextBox21 = ListBox1.Column(18)
TextBox22 = ListBox1.Column(19)
TextBox23 = ListBox1.Column(20)
TextBox24 = ListBox1.Column(21)
TextBox25 = ListBox1.Column(22)
TextBox26 = ListBox1.Column(23)
LastRow = Sheets("Database").Cells(Rows.Count, "B").End(xlUp).Row
Sheets("Database").Range("B2:B" & LastRow).Find(What:=ListBox1.Value,
LookIn:=xlValues, LookAt:=xlWhole).Activate
say = ActiveCell.Row
Sheets("Database").Range("A" & say & ":Y" & say).Select
Have a look at the following demo:
Option Explicit
Private Sub UserForm_Initialize()
With ListBox1
.ColumnCount = 2
.AddItem
.List(.ListCount - 1, 0) = "Test"
.List(.ListCount - 1, 1) = "abc"
.AddItem
.List(.ListCount - 1, 0) = "Test2"
.List(.ListCount - 1, 1) = "def"
End With
End Sub
Private Sub ListBox1_Click()
Dim SelectedItem As Long
Dim j As Long
Dim ctrls As Variant
Dim TextBoxCounter As Long
SelectedItem = ListBoxSelectedIndex(Me.ListBox1)
ctrls = Array(TextBox1, TextBox2)
For j = 0 To Me.ListBox1.ColumnCount - 1
If j <> 9 And j <> 10 And j <= UBound(ctrls) Then
ctrls(j).Text = Me.ListBox1.List(SelectedItem, TextBoxCounter)
TextBoxCounter = TextBoxCounter + 1
End If
Next j
End Sub
Private Function ListBoxSelectedIndex(lBox As msforms.ListBox) As Long
With lBox
For ListBoxSelectedIndex = 0 To .ListCount - 1
If .Selected(ListBoxSelectedIndex) Then Exit For
Next ListBoxSelectedIndex
End With
End Function
This produces:
This can be easily expanded with the rest of your controls for your situation

How to appear in the right column?

I have a problem which is the data did not appear in the column. Only the first data. Name data should appear at column B9.
And fyi, name will appear at column A in last data.
The data will come out like this;
Where should I need to fix my error?
And the error I think is at this line -
ws.Cells(totalRows + 1, 1) = txtName.Text
Hope anyone of you can help me.
Thank you in advance.
Private Sub cmdAdd_Click()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Master Data")
Dim Addme As Range, str As String, totalRows As Long
Set Addme = ws.Cells(ws.Rows.Count, 3).End(xlUp).Offset(1, 0)
Application.ScreenUpdating = False
If Me.txtName = "" Or Me.cboAmount = "" Or Me.cboCeti = "" Then
MsgBox "There is insufficient data, Please return and add the needed information"
Exit Sub
End If
totalRows = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
totalRows = Application.WorksheetFunction.Max(totalRows, 3)
ws.Cells(totalRows + 1, 1) = txtName.Text
If cbWhatsapp.Value = True Then
str = "Whatsapp, "
End If
If cbSMS.Value = True Then
str = str & "SMS, "
End If
If cbEmail.Value = True Then
str = str & "Email, "
End If
If cbFacebook.Value = True Then
str = str & "Facebook, "
End If
If cbPhoneCall.Value = True Then
str = str & "Phone Call, "
End If
str = Left(str, Len(str) - 2)
ws.Cells(totalRows + 1, 2) = str
If optYes.Value = True Then
ws.Cells(totalRows + 1, 3) = "Yes"
ElseIf optNo.Value = True Then
ws.Cells(totalRows + 1, 3) = "No"
End If
ws.Cells(totalRows + 1, 4) = cboAmount.Value
ws.Cells(totalRows + 1, 5) = cboCeti.Value
ws.Cells(totalRows + 1, 6) = txtPhone.Text
ws.Cells(totalRows + 1, 7) = txtEmail.Text
ws.Range("B9:H10000").Sort Key1:=Range("F9"), Order1:=xlAscending, Header:=xlGuess
MsgBox "Your data was successfully added"
Sheet1.Select
On Error GoTo 0
Exit Sub
End Sub

Resources