I am very much of a beginner with VBA so forgive any sloppiness. I am looking for a macro or another way to print labels on a Zebra printer as soon as a value is inputted into a specific column in a spreadsheet. This is not designed to work for as soon as the value is inputted, I was just testing to see whether the printer prints a BARCODE which is the most important part of this, so I used the code below which I lifted from here. The print area is the selected cell. It contains a 12-digit number to be printed as a barcode label:
Sub ZEBRA_LABEL()
Dim r As Long
With ActiveSheet
With .PageSetup
.FitToPagesWide = 1
.FitToPagesTall = False
End With
For r = 5 To 20
If Range("E" & r) <> "" Then 'the r values correspond with row numbers
With .PageSetup
.PrintArea = "$B$" & r & ":$E$" & r + 3
ActiveSheet.PrintOut copies:=Range("A" & r).Value, collate:=True, IgnorePrintAreas:=False
End With
End If
Next
End With
End Sub
However, this gives me an "Run time error 1004 - Application-defined or Object-defined error" (which makes sense because Cell.Value is not an object) and if I remove the .Value from the ActiveSheet.PrintOut statement the Zebra printer does not print a barcode but the appearance of the cell itself.
Anyone have any ideas about how to make this work? I tried almost every solution I could find online but nothing has worked for me
Related
Updated and Edited
I am new to this whole world, but here is my issue as it stands:
As the userform initializes the below code applies a filter to my 'clean import', copies column a into a temp sheet, which is what the listbox uses to populate itself.
Set ws = ThisWorkbook.Worksheets("Clean_Import")
ws.Activate
On Error Resume Next
ws.ShowAllData
On Error GoTo 0
ws.Range("A1:K1000").AutoFilter Field:=5, Criteria1:="<1"
Range("A:A").Select
Selection.SpecialCells(xlCellTypeVisible).Select
Selection.Copy
Sheets("TempSheet").Select
Columns("A:A").Select
Range("A2").Activate
ActiveSheet.Paste
ODList1.List = Sheets("TempSheet").Range("A2:A100").Value
End Sub
From then in it is just double clicking on the list box to lookup the selected items and vlook some data into text boxes.
With Me.ODList1
For i = 0 To .ListCount - 1
If .Selected(i) Then
TextBox11.Value = Application.VLookup(.List(i, 0), Sheet3.Range("A1:K100"), 3)
TextBox12.Value = Format(Application.VLookup(.List(i, 0), Sheet3.Range("A1:K100"), 7), "dd / mm / yyyy")
TextBox13.Value = Application.VLookup(.List(i, 0), Sheet3.Range("A1:K100"), 10)
Exit For
End If
Next
End With
This code works in all but one of my scenarios. I realise now if i select the list box item that happens to be the first line in the range OR the last in the range in my 'clean import' then I get the following error.
Run-Time error '-2147352571 (80020005)': Could not set the value
property. Type mismatch.
The only thing I can think is that the value doesn't match, but that doesn't seem possible as the list box is populated from a direct copy from the range it is vlooking through
I look forward to hearing your thoughts,
Cheers,
Bill
That is happening because the Vlookup is not able to find a match. Here is a simple way to reproduce the error
Private Sub CommandButton1_Click()
TextBox1.Value = Application.VLookup("Sid", Sheet1.Range("A1:K100"), 3)
End Sub
To handle this, you need to introduce proper error handling. Here is an example
Dim Ret As Variant
Ret = Application.VLookup("Sid", Sheet1.Range("A1:K100"), 3)
If IsError(Ret) Then
TextBox1.Value = "Error"
Else
TextBox1.Value = Ret
End If
I made some small adjustments to the way I brought the data in and problem went away.
Not really sure where the issue was creeping in. But it crept back out again.
I already have a barcode scanner VBA function, that recognizes the barcode number, but the problem I have is that I have to click enter every time, is there any way to do it automatically and store the count in a certain column? Currently it works if I enter the same value stored in column B, it will count the records in column C, but I want to avoid hitting enter every time
This is what I got so far
Private Sub btnAdd_Click()
Dim TargetCell As Range
If WorksheetFunction.CountIf(Sheets("Sheet1").Columns(2), TextBox1.Value) = 1 Then
Set TargetCell = Sheets("Sheet1").Columns(2).Find(TextBox1.Value, , xlValues, xlWhole).Offset(0, 1)
TargetCell.Value = TargetCell.Value + 1
Else
MsgBox "Code not found"
End If
Me.Hide
End Sub
It's hard to say what you have. For example, who presses the button? Or, does your scanner enter a return. I think the code below should work under any circumstances. Please try it.
Private Sub TextBox1_Change()
Dim TargetCell As Range
Dim Qty As Long
With TextBox1
If Len(.Value) = 3 Then
Set TargetCell = Worksheets("Sheet1").Columns(2) _
.Find(.Value, , xlValues, xlWhole)
If TargetCell Is Nothing Then
MsgBox """" & .Value & """ Code not found"
Else
With TargetCell.Offset(0, 1)
Qty = .Value + 1
.Value = Qty
End With
Application.EnableEvents = False
TextBox1.Value = "Count = " & Qty
Application.EnableEvents = True
End If
.SelStart = 0
.SelLength = Len(.Value)
End If
End With
End Sub
I think you have a user form and in this form you have a text box called TextBox1. If so, the code should be in the user form's code module. If you have a text box in your worksheet paste the code to the code module of the sheet on which the text box resides.
Now, you need to adjust this line of code If Len(.Value) = 3 Then to determine when to process the data. This is because the Change event will occur whenever even a single character is entered. I tested with 3 characters. Change the number to a value equal to the length of the numbers you scan in. In theory that still leaves the CR hanging which your scanner might also send. If that causes a problem experiment with >= in place of the = in my code.
The code will add the scan to the existing quantity, just as you had it, and indicate the new total in the text box, in case you are interested. You might replace this with "OK". The code will select the text it enters. Therefore when you enter something else, such as a new scan, it will be over-written without extra clicks being required.
I have a file that has a bunch of Cells in the A column (1500) that look like this:
Perfect Imperfection;"Kevin Gates";"Luca Brasi 2: Gangsta Grillz";1
or
Perfect Imperfection;"Kevin Gates";"Luca Brasi 2: Gangsta Grillz";0
I am trying to delete cells that end in ;1
Note that some song titles have a 1 in them, and others take the form of:
Perfect Imperfection;;;1
I'm using the following code from a different Stack Overflow post that I have edited slightly:
Sub DeleteRowsWithX()
maxRow = ActiveSheet.UsedRange.Rows.Count
MsgBox (maxRow)
For i = 1 To maxRow
Do While (StrComp(ActiveSheet.Cells(i, 1).Text, ";1", vbTextCompare) = 0)
Rows(i).Select
Selection.Delete Shift:=xlUp
MsgBox ("Deleted")
Loop
Next
End Sub
If it helps, here are some examples of the file:
Perfect Imperfection;"Kevin Gates";"Luca Brasi 2: Gangsta Grillz";1
Perfect Strangers;"Lil Wayne";"Tha Carter V";1
Perplexing Pegasus;"Rae Sremmurd";;1
Phone Numbers Wiz Khalifa;;;0
Piano Man;"Billy Joel";;1
Picasso Baby Jay Z;;;0
Pick Up the Phone ft Young Thug Travis Scott;;;0
Picture;"Kid Rock";;1
Pillowtalk Conor Maynard;;;1
Pimp Juice;Nelly;Nellyville;1
Pinball Wizard;"The Who";;1
Pink Toes Childish Gambino;;;1
Which should look like:
Phone Numbers Wiz Khalifa;;;0
Picasso Baby Jay Z;;;0
Pick Up the Phone ft Young Thug Travis Scott;;;0
However, nothing is deleting. Can anybody advise? NOTE -- this not need to be done in VBA, I just want to delete rows that end in 1
Requirements: Delete entire row of values in column 1 that end with ";1"
For this kind of requirements suggest the use of AutoFilter and SpecialCells to delete all the target rows at once.
Try this:
Sub AutoFilter_To_DeleteRows()
With ActiveSheet
Application.Goto .Cells(1), 1
Rem Add a temporary header to avoid indiscriminate deletion of the first row.
.Cells(1).EntireRow.Insert
.Cells(1).Value2 = "Temporary Header"
Rem Filter values ending with ";1"
.Columns(1).AutoFilter Field:=1, Criteria1:="=*;1"
Rem Delete all resulting rows
.Columns(1).SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
End Sub
Keeping the answer close to the code that you have written.
You need to loop from the bottom of your list to the top. That way when rows are deleted, you do not skip rows. This can be done in your For loop by starting with the bottom of the list and moving backwards to the first row using Step -1.
The Right function can be used to test the last two characters of the cell value to see if they match to ;1.
The Do While can be removed.
The MsgBox's have been expanded to provide more detail when testing. They can be commented out once you are happy with the way the code is running.
Sub DeleteRowsWithX()
maxRow = ActiveSheet.UsedRange.Rows.Count
MsgBox "No. of Rows: " & maxRow
For i = maxRow To 1 Step -1
ValOfCell = ActiveSheet.Cells(i, 1).Value2
If Right(ValOfCell, 2) = ";1" Then
Rows(i).Delete Shift:=xlUp
MsgBox "Row: " & i & vbCrLf & "Value: " & ValOfCell & vbCrLf & "has been deleted."
End If
Next
End Sub
Jerry, I could not get StrComp to work the way I wanted, so I used Mid & Len to accomplish what you need. This will work since all the song titles end with ";?". Also, I did not add to the code, but consider doing everything you can to not use the Select method - this can lead to complications.
Sub DeleteRowsWithX()
Dim maxrow As Integer
Dim i As Integer
maxrow = ActiveSheet.UsedRange.Rows.Count
For i = 1 To maxrow
Do While Mid(Cells(i, 1).Text, Len(Cells(i, 1).Text) - 1, 2) = ";1"
Rows(i).Select
Selection.Delete Shift:=xlUp
MsgBox ("Deleted")
Loop
Next
End Sub
I am currently working on a bear of a worksheet that is designed to show the change of individual parameters over the same time interval using the Backdoor technique detailed at http://peltiertech.com/excel/chartshowto/panelunevenscales.html.
Basically, I have it set up as a template where 5 columns of data (which vary in length of rows) can be pasted into columns A-F starting at row 12. The time column that I would like to filter is in column A and I basically want to make it so that 2 combo boxes (ComboBox1 and ComboBox2) can be used to set an upper and lower time limit and filter out any other data. I'm hoping I can turn this into a dynamic chart that will resize the x-axis to show only the selected time period.
I'm still relatively new to using VBA and I did a good bit of searching and the only thing I could find that seemed related was the question answered at http://www.ozgrid.com/forum/showthread.php?t=54376. I tried the following code and kept getting errors:
Sub TimeFilter()
Crit1 = Format(ComboBox1, "0")
Crit2 = Format(ComboBox2, "0")
.AutoFilterMode = False
.Range("A12:L10000").AutoFilter
.Range("A12:L10000").AutoFilter Field:=1, Criteria:=">=" & crit1, Operator:=xlAnd, Criteria2:="<=" & crit2
End Sub
Any ideas on why it might not be working? Any help or guidance is appreciated!
****EDIT****
Here is the updated FULL code for the spreadsheet I'm using, and with the TimeFilter script I get a "Run-time error '1004', AutoFilter method of Range class failed":
**The time that I am filtering by is in 0.2 second intervals with the format MM:SS.X.
Sub CreateComboBoxes()
Dim Cell As Range
Dim sht As Worksheet
Set sht = ThisWorkbook.Worksheets("Sheet1")
Set Cell = Range("I8")
With Cell
sht.DropDowns.Add(.Left, .Top, .Width, .Height).Name = "ComboBox1"
End With
Set Cell = Range("K8")
With Cell
sht.DropDowns.Add(.Left, .Top, .Width, .Height).Name = "ComboBox2"
End With
End Sub
Sub TimeFilter()
Crit1 = Format(ComboBox1, "0")
Crit2 = Format(ComboBox2, "0")
Worksheets("Sheet1").AutoFilterMode = False
Worksheets("Sheet1").Range("A12:L10000").AutoFilter
Worksheets("Sheet1").Range("A12:L10000").AutoFilter Field:=1,Criteria1:=">=" & Crit1, Operator:=xlAnd, _
Criteria2:="<=" & Crit2
End Sub
I preface this by stating that this is not an answer but an explanation in the use of With, End With statement. The comment section does not offer the formatting tools required to do so properly
The With, End With statements save you on typing the same bits over and over.
ThisWorkbook.Worksheets("Sheet1").UsedRange.Font.ColorIndex = 3
ThisWorkbook.Worksheets("Sheet1").UsedRange.Font.Bold = True
ThisWorkbook.Worksheets("Sheet1").UsedRange.Font.Size = 15
ThisWorkbook.Worksheets("Sheet1").UsedRange.Font.Name = "Times new Roman"
Can also be written as
With ThisWorkbook.Worksheets("Sheet1").UsedRange.Font
.ColorIndex = 3
.Bold = True
.Size = 15
.Name = "Times new Roman"
End With
You'll notice the "." in front of the lines in between the with end with statement, this means it should be read as a continuation of what is set by the With statement.
I have a table with a fixed number of columns, but the number of rows vary week on week.
Is there a macro I can create to set the print area automatically of this table?
I would combine a dynamically resizing named range with a VBA method.
First create a named range, MyNamedRange: (Assuming your table begins at $A$1 and your table has headers)
=OFFSET(A1,0,0,COUNTA(A:A)-1,COUNTA(1:1))
Then just execute a line of VBA:
ActiveSheet.PageSetup.PrintArea = "MyNamedRange"
Just use this simple code:
Private Sub prnt()
On Error Resume Next
Cells(1, 1).Select
With ActiveSheet.PageSetup
.PrintArea = Range(ActiveCell, ActiveCell.SpecialCells(xlCellTypeLastCell)).Select.Address
.Orientation = xlLandscape
.LeftHeader = "&p/&N"
.LeftFooter = ActiveWorkbook.FullName 'to show address
.PrintTitleRows = "$1:$5" 'repeat at top
.Zoom = False
.Orientation = xlLandscape
.FitToPagesWide = 1 'to print in 01 page
.FitToPagesTall = False 'to print in 01 page
End With
End Sub
If you're wanting to print the whole sheet always, you can actually just clear the print area and it will default to the amount of the sheet that is filled with data. If you're wanting not to hide some columns, wtfsven's answer is perfect.
I guess this is a pretty late response...
The solution above didn't work for me in Excel 2007 so I used
begin_column = 1
end_column = 5
begin_row = 1
end_row = 30
'converting the numbers to uppercase letters
temp_begin_column = Chr(first_column + 64)
temp_end_column = Chr(second_column + 64)
ActiveSheet.PageSetup.PrintArea = "$" & temp_begin_column & "$" & begin_row & ":$" & temp_end_column & "$" & end_row
This may seem like a complicated solution but its the only thing that reliably worked for me
I have tried this and it Worked for me.
StartColumn="A"
StartRow=1
EndColumn="B"
EndRow=10
ActiveSheet.PageSetup.PrintArea = StartColumn & StartRow & ":" & EndColumn & EndRow
ActiveSheet.PageSetup.PrintArea = "A1:B10"
Or
ActiveSheet.PageSetup.PrintArea = "$" & StartColumn & "$" & StartRow & ":" & "$" & EndColumn & "$" & EndRow
ActiveSheet.PageSetup.PrintArea = "$A$1:$B$10"
ActiveSheet.PageSetup.PrintArea = "MyNamedRange" as proposed above by Stephen Collins does not work for me.
But if I typed a slightly modified version:
ActiveSheet.PageSetup.PrintArea = MyNamedRange.Address then it works perfectly in my context.
I had Application.ReferenceStyle = xlR1C1 activated and not xlA1.
Note: ActiveSheet.PageSetup.PrintArea = MyNamedRange.Address(ReferenceStyle:=xlR1C1) would not work for me.
Similarly,
ActiveSheet.PageSetup.PrintArea = StartColumn & StartRow & ":" & EndColumn & EndRow as proposed above by Bhanu Pratap works indeed very well, 1st time. Bu not so easy to manage programmatically (column letters).
But using "R" & StartRow & "C" & StartColumn & ":" & "R" & EndRow & "C" & EndColumn --- does not work for me either. So, consistent.
Looking at https://learn.microsoft.com/en-us/office/vba/api/excel.pagesetup.printarea
it states that "you use the Address property to return an A1-style address."
So, it seems to be an expected VBA behaviour not to use xlR1C1 while it would be much easier to use programmatically.
My simple way around it:
Set MyNamedRange = Worksheets(i_sheet_idx).Range(Cells(StartRow, StartColumn), Cells(EndRow, EndColumn)) -- using the same variables as suggested above by Bhanu Pratap.
Then
ActiveSheet.PageSetup.PrintArea = MyNameRange.Address ' which does the job for me.
So, I can programmatically play with the start/End Row/Columns easily.
Using offset as suggested above should work also to change the range but this is independent from the programmatic difficulty encountered here in VBA to specify the range address in a way VBA would accept to swallow without error. I would not want to count the strange & unclear VBA errors I had on these trials. I don't use VBA often & never program otherwise (hence the struggle above). The goal was to print automatically, smartly & recurrently a large number of parts of a large worksheet following a pattern.
NB: possibly unrelated, I encountered in the debugging phase - just on the PageSetup.PrintArea line - as above a strange phenomenon where even if no error (so the code following later after rerun a fully expected & controlled path), my code would jump - sometimes - to a totally different sub or function in another workbook without reason (I have another personal workbook storing a number of work macros in several modules). It happens 4 times in tests. I tried to find events that could trigger this but could not find one. Sometimes it was the same sub/function being triggered, sometimes it was a different one, with no logical connection. But I noted that I had seen the same function being triggered in another situation before (see its basic code below), without good reason. So, something must happen at application level. In this "short piece of code" just written to test the above, I introduced later an error handler to catch err.number in case a problem would occur but of course, it did not reoccur.
I suppose that closing & restarting Excel (2013 here) should fix this error. This has happened to me before once in Excel 2010. A pointer going nuts but with some insistence, a repeated folly which supposes some logic behind. Weird.
Here is the function most often triggered in another module in another workbook (while not being programmatically activated at all, I repeat): it does not make logical sense to me but so it is:
Function HLink(rng As Range) As String
'extract URL from hyperlink
If rng(1).Hyperlinks.Count Then HLink = rng.Hyperlinks(1).Address
End Function
The other sub being activated did not make more apparent sense.