From our drawing program we receive a sheet with data for sawing sheet material. We want to make a sticker for each unique plate.
The idea is, rearrange the data into a sticker format on a new sheet.
jpeg image for example.
Sub Platen_stickers()
Application.ScreenUpdating = False
Dim i As Long
Dim j As Long
Dim xLast As Long
Dim rw As Range
Dim aantalrng As Range
Dim aantal As Range
Dim plaattype As Range
Dim Merk As String, Label As String, Lengte As String, Breedte As String
Dim stickeraantal As Byte, stickergemaakt As Byte
Dim sticker As Range
Dim row As Range
Dim x As Long
On Error Resume Next
xLast = ActiveWorkbook.Sheets(1).Cells(Rows.Count, "B").End(xlUp).row 'searching last filled cell in column B
For i = 8 To xLast Step 1
If Sheets(1).Cells(i, "B").Value2 = "Code" Then 'searching for header "Code" in column B
Set plaattype = Sheets(1).Cells(i + 1, "B") 'defining the cell below "Code" as range "plaattype"
Set aantal = plaattype.Offset(0, 2) 'defining cell in row below "Code" and in column D as range "aantal"
Set aantalrng = Range(aantal, aantal.End(xlDown)) 'defining all numbers in column D under this header as range "aantalrng"
'inserting new sheet for stickers after current last sheet
ActiveWorkbook.Sheets.Add After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count)
ActiveSheet.Name = plaattype.Value2 'editing sheet name to current type
Set sticker = ActiveSheet.Range(1, 1) 'defining cell A1 of current sheet as current sticker
With ActiveSheet.Range("A1:F31") 'adjusting cell dimensions of range A1:F32 to sticker format (96 sticker per sheet)
.Columns("A:F").ColumnWidth = 18.14
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
End With
For Each rw In ActiveSheet.Range("A1:F32").Rows
If rw.row Mod 2 = 0 Then
rw.RowHeight = 5.25
Else: rw.RowHeight = 53.25
End If
Next rw
With ActiveSheet.PageSetup 'adjusting print settings to fit stickersheet
.CenterHorizontally = True
.CenterVertically = True
.LeftMargin = Application.CentimetersToPoints(0)
.RightMargin = Application.CentimetersToPoints(0)
.TopMargin = Application.CentimetersToPoints(0.6)
.BottomMargin = Application.CentimetersToPoints(0.6)
.HeaderMargin = Application.CentimetersToPoints(1.3)
.FooterMargin = Application.CentimetersToPoints(1.3)
.Zoom = 87
End With
x = 1 'setting sticker count on 1
'creating the actual sticker
For Each row In aantalrng 'running through current data for creating stickers
stickergemaakt = 0 'resetting counter made sticker in this row
stickeraantal = aantalrng.Cells(row, 1).Value 'checking how many stickers this row needs making (=value of column D)
Do Until stickergemaakt > stickeraantal 'looping until made stickers is needed stickers
Merk = aantalrng.Cells(row, 1).Offset(0, -1).Value 'collecting sticker input
Label = aantalrng.Cells(row, 1).Offset(0, -3).Value
Lengte = aantalrng.Cells(row, 1).Offset(0, 1).Value
Breedte = aantalrng.Cells(row, 1).Offset(0, 2).Value
sticker.Value = Merk & " " & Label & vbCrLf & Lengte & " x " & Breedte & " mm" & vbCrLf & plaattype 'writing sticker input in format on current cell on sticker sheet
If x < 6 Then
Set sticker = sticker.Offset(0, 1) 'adjusting to new empty sticker cell => next column
x = x + 1
ElseIf x = 6 Then
sticker = sticker.Offset(1, -6) 'until reached 6 columns, then next row to start again
x = 1
End If
stickergemaakt = stickergemaakt + 1 'adding counter made sticker with 1
Loop
stickeraantal = 0 'resetting number of stickers needed to zero for next row
Next row
End If
Next
Application.ScreenUpdating = True
End Sub
The first part, inserting extra sheets and adjusting to the sticker sizes, works in my sample file.
The second part, filling the stickers with the data, I can't get started.
I suspect I'm doing something wrong with declaring the range per header.
But whatever I adjust in it, the second part doesn't work and sometimes the first part doesn't either.
Related
I am trying to create a program that deletes all rows without information in columns B-G and then rearranges the data from a vertical orientation to a horizontal one.
The data is only in columns A-G arranged so that every couple rows (the number is not constant), a row of dates appears. I want every row with dates to be pasted horizontally from each other and all of the data in between the dates to move corresponding with their dates (including column A).
The part that deletes empty rows works well. However, as I tried to write the rearrangement program, I kept on getting an
"Object Required"
error that appeared in the sub line (AKA the first line). Can someone help me resolve this issue? The code is pasted below.
Sub MovingDeletion()
Set rngRange = Selection.CurrentRegion
lngNumRows = rngRange.Rows.Count
lngFirstRow = rngRange.Row
lngLastRow = lngFirstRow + lngNumRows - 1
columns("B").Select
lngCompareColumn1 = ActiveCell.Column
columns("C").Select
lngCompareColumn2 = ActiveCell.Column
columns("D").Select
lngCompareColumn3 = ActiveCell.Column
columns("E").Select
lngCompareColumn4 = ActiveCell.Column
columns("F").Select
lngCompareColumn5 = ActiveCell.Column
columns("G").Select
lngCompareColumn6 = ActiveCell.Column
columns("A").Select
lngCompareColumn7 = ActiveCell.Column
Set MedicationRow = 0
'Deletion Code (Works Fine)
For lngCurrentRow = lngLastRow To lngFirstRow Step -1
Mrow = True
If (Cells(lngCurrentRow, lngCompareColumn1).Text = "" And Cells(lngCurrentRow, lngCompareColumn2).Text = "" And Cells(lngCurrentRow, lngCompareColumn3).Text = "" And Cells(lngCurrentRow, lngCompareColumn4).Text = "" And Cells(lngCurrentRow, lngCompareColumn5).Text = "" And Cells(lngCurrentRow, lngCompareColumn6).Text = "") Then _
Rows(lngCurrentRow).Delete
'Rearrangement Code (Does not work. Gives Object Requiered error)
Dim counter As Integer
Dim NextRow As Integer
Dim i As Integer
i = lngCurrentRow
counter = 0
Number = 0
If (Cells(lngCurrentRow, lngCompareColumn7).Text <> "Days") Then
counter = counter + 1
If counter > 1 Then
NextRow = lngCurrentRow - 1
While (Cells(NextRow, lngCompareColumn7).Text <> "Days")
NextRow = NextRow - 1
Number = Number + 1
Wend
End If
Range("A" & CStr(i) & ":G" & CStr(NextRow)).Cut Range("H1" & CStr(i) & ":P" & CStr(NextRow))
End If
Next lngCurrentRow
End Sub
I am essentially trying to slice my "master excel" file into a bunch of new files using the same data. I am able to create the new file, make an entry and then save; however, I am unable to add multiple entries into one file. I feel like I'm brain farting on some basic coding logic.
The master excel file looks as follows:
A B C D
1 XXX-01 100 Description1 4
2 XXX-01 104 Description2 2
3 XXX-01 209 Description3 3
4 XXX-02 102 Description4 5
5 XXX-02 355 Description5 1
6 XXX-02 322 Description6 1
7 XXX-02 943 Description7 9
8 XXX-02 231 Description8 4
9 XXX-03 124 Description9 4
10 XXX-03 555 Description10 2
Where
A: GroupID
B: Part_Number
C: Description
D: Quantity
My desire, from the above, would to make 3 excel files (XXX-01, XXX-02, XXX-03) where each file contains it's respective data.
For instance, XXX-01.xlsx would look like the following:
A B C D
1 Item# Part Description Qty
2 1 100 Description1 4
3 2 104 Description2 2
4 3 209 Description3 3
Where row 1 is for headers that are the same for each XXX-## file.
In order to establish a baseline of where my code is at: the following works to create the file insert one row, but will then close and overwrite the previous file. (Stolen from: Create, name, and populate new workbook with data)
Sub CreateBooks()
Dim oCell As Excel.Range
Dim oWorkbook As Excel.Workbook
Application.DisplayAlerts = False
For Each oCell In Range("A:A")
If oCell.Value = "" Then Exit For
Set oWorkbook = Workbooks.Add
oWorkbook.Sheets(1).Cells(1, 1).Value = oCell.Offset(0, 1).Value
oWorkbook.Close True, oCell.Value
Next oCell
Application.DisplayAlerts = True
End Sub
I added the following in order to insert my save path into column A of the Master:
Dim Path As String
Path = "C:\Users\MyComputer\Documents"
For Each oCell In Range("A:A")
If oCell.Value = "" Then Exit For
oCell.Value = Path & oCell.Value
Next oCell
My goal with the below edits was to get the for loop to repeat if the cell below oCell is equivalent to the value of oCell. Perhaps a Do While loop would be more applicable here; however.
Dim Row_Counter As Integer
For Each oCell In Range("A:A")
If oCell.Value = "" Then Exit For
Set oWorkbook = Workbooks.Add
oWorkbook.Sheets(1).Cells(Row_Counter, 2).Value = oCell.Offset(0, 1).Value
oWorkbook.Sheets(1).Cells(Row_Counter, 3).Value = oCell.Offset(0, 2).Value
oWorkbook.Sheets(1).Cells(Row_Counter, 4).Value = oCell.Offset(0, 3).Value
For Each Next_oCell In Range("A:A")
If Next_oCell.Value = oCell.Value Then
Row_Counter = Row_Counter + 1
oWorkbook.Sheets(1).Cells(Row_Counter, 2).Value = Next_oCell.Offset(0, 1).Value
oWorkbook.Sheets(1).Cells(Row_Counter, 3).Value = Next_oCell.Offset(0, 2).Value
oWorkbook.Sheets(1).Cells(Row_Counter, 4).Value = Next_oCell.Offset(0, 3).Value
End If
Next Next_oCell
That being said, I am still only getting the one file that is being overwritten. I think my issue (or at least one of them) is that I don't have a means of saying "go through all rows with this value in column A, then skip to the first row with a new number."
Any help would be greatly appreciated!
Here's one approach:
Sub Divide()
Dim dict As Object, v, k, c As Range, i As Long, sht As Worksheet
Set dict = CreateObject("scripting.dictionary")
'collect all the distinct values and matching cell references
For Each c In Range("A:A")
v = c.Value
If Len(v) = 0 Then Exit For
If Not dict.exists(v) Then dict.Add v, New Collection 'new key if needed
dict(v).Add c 'add the cell to the appropriate collection
Next c
'process each group id in turn
For Each k In dict.keys
'create and save a workbook (to the same location as this workbook)
With Workbooks.Add
.SaveAs ThisWorkbook.Path & "\" & k & ".xlsx"
.Sheets(1).Range("a1").Resize(1, 4).Value = _
Array("Item#", "Part", "Description", "Qty")
i = 1
'process each cell in the collection for this Group
For Each c In dict(k)
.Sheets(1).Cells(i + 1, 1).Value = i
.Sheets(1).Cells(i + 1, 2).Resize(1, 3).Value = _
c.Offset(0, 1).Resize(1, 3).Value
i = i + 1
Next c
.Close True 'save changes
End With
Next k
End Sub
Does this solution work?
Sub SeperateMasterFile()
'
' This part of the macro sorts Column A in Ascending Order
Dim lRowD As Long
Dim lRowA As Long
'Find the last non-blank cell in column D(4)
lRowD = Cells(Rows.Count, 4).End(xlUp).Row
'
'Find the last non-blank cell in column A(1)
lRowA = Cells(Rows.Count, 1).End(xlUp).Row
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add2 Key:=Range("A1"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SetRange Range("A1:D" & lRowD)
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Dim LastI As Integer
Dim NewValueInColumnA As String
Dim NewValueInColumnARowNumber As Integer
For I = 1 To lRowA + 1
LastI = I - 1
'If LastI = 0 then we will make LastI = 1, because Range"(A0)".select would be invalid
If LastI = 0 Then
I = 1
End If
'When the For loop starts the following if statement
'will put the value in A1 into the variable NewValueInColumnA
If NewValueInColumnA = "" Then
NewValueInColumnA = Range("A1").Text
NewValueInColumnARowNumber = 1
End If
If NewValueInColumnA = Range("A" & I) Then
Else
'If A3 has a different value to A2, then the following code selects A1:D2
'If A7 has a different value to A6, then the following code selects A3:D6
Range("A" & NewValueInColumnARowNumber & ":D" & LastI).Select
NewValueInColumnARowNumber = I
NewValueInColumnA = Range("A" & I)
'The following code now runs the macro called 'MoveToNewWorkBook'
Call MoveToNewWorkbook
End If
Next I
End Sub
Sub MoveToNewWorkbook()
'
' MoveToNewWorkbook Macro
'
Selection.Copy
Workbooks.Add
Range("A2").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Range("A1").Value = "Item#"
Range("B1").Value = "Part"
Range("C1").Value = "Description"
Range("D1").Value = "QTY"
ActiveWorkbook.SaveAs Filename:="C:\Users\HP\Documents\" & Range("A2").Text & ".xlsx", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
ActiveWindow.Close
End Sub
The group column in my table contains a value as either 1 or 2 . I want to copy the row with value as 1 to Sheet2 and rows with values as 2 to sheet3 using a button. Also it should show error message if cells are left blank or if value is neither 1 nor 2.
Roll no meter width group
112 150 130 1
Since i am new to coding i have following this approach
check if the cell is empty and generate an error message
check if the cell contains value other than 1 or 2 and generate error message
finally copy the row with values as 1 to Sheet2 and rest all in sheet3
I need help in doing this is an effective way. As i have to keep the size of file down
enter code here
Private Sub CommandButton2_Click()
Dim i As Integer
p = Sheet1.Range("l1").Value 'no. of filled cells in the range
Application.DisplayAlerts = False
Sheet1.Activate
''checking if the range is empty
For i = 29 To p + 29
If Sheet1.Range("l" & i).Value = "" Then
MsgBox ("PLEASE ENTER THE SHRINKAGE GROUP FOR CELL NO. l" & i)
Range("L" & i).Activate
End
End If
Next i
'' checking if the range contains values other than 1 or 2
For i = 29 To p + 29
If Sheet1.Range("l" & i).Value <> 1 And Sheet1.Range("l" & i).Value <> 2 Then
MsgBox ("SHADE GROUP DOES NOT EXIST FOR CELL NO. l" & i)
Range("L" & i).Activate
End
End If
Next i
' sort based on the group
Range("a29:L300").Sort _
Key1:=Range("l29"), Header:=xlYes
'count the number of rolls in group 1
Dim x, y As Long
Dim a, b As Integer
x = Range("L" & Rows.Count).End(xlUp).Row
If x < 29 Then x = 29
a = Application.WorksheetFunction.CountIf(Range("L12:L" & x), 1) + 28
Range("M1").Value = a
' count the number of rolls in group 2
y = Range("L" & Rows.Count).End(xlUp).Row
If y < 29 Then y = 29
b = Application.WorksheetFunction.CountIf(Range("L12:L" & x), 2)
Range("n1").Value = b
'' copying groupwise to different sheet
Sheet1.Range("a29", "l" & a).Copy
Sheet2.Range("a5").PasteSpecial xlPasteAll
Sheet2.Range("a5").PasteSpecial xlPasteValuesAndNumberFormats
'' copying group 2
Sheet1.Range("a" & a + 1, "l" & a + b).Copy
Sheet5.Range("a5").PasteSpecial xlPasteAll
Sheet5.Range("a5").PasteSpecial xlPasteValuesAndNumberFormats
End Sub
Create named ranges for your source data and for the rows after which you want it to be copied. In this example I've used "source", "range1" and "range2". Then the following code copies the source data into the appropriate place:
Sub copyData()
Dim source As Range, range1 As Range, range2 As Range
Dim r As Range
Set source = Range("source")
Set range1 = Range("range1")
Set range2 = Range("range2")
For Each r In source.Rows
If r.Cells(1, 4).Value = 1 Then
copyRow r, range1
ElseIf r.Cells(1, 4).Value = 2 Then
copyRow r, range2
Else
' handle error here
End If
Next r
End Sub
Sub copyRow(data As Range, targetRange As Range)
Set targetRange = targetRange.Resize(targetRange.Rows.Count + 1, targetRange.Columns.Count)
For i = 1 To 3
targetRange.Cells(targetRange.Rows.Count, i).Value = data.Cells(1, i).Value
Next i
End Sub
There's probably a much more elegant way of doing this involving array formulae, but this should do the trick.
For validating that each cell contains only "1" or "2", you can include additional code where I've put a comment, but you'd be better off handling this as a data validation.
As the title says - This code will search Sheet1,Column I for a certain word; e.g "White" and paste all matches into the set row on sheet 2. White represents a martial arts white belt and will paste all student names who are listed as white belt into a set row number/page on sheet2, however i can only fit 30 names on a page and some months there are more than 30 white belts so i need it to paste the first 30 names into the set rows and the remainder in the next page which lets say for example is 5 rows down from the 30th white belt.
There are hundreds of students and 23 different belt levels which always change row numbers on sheet 1 so a fixed method would not work. Please help.
Sub ADULTClearAndPaste()
Dim lr As Long, lr2 As Long, r As Long
Set Sh1 = ThisWorkbook.Worksheets("ADULT members to cut & past")
Set Sh2 = ThisWorkbook.Worksheets("ADULT Sign On Sheet")
Sh1.Select
lr = Sh1.Cells(Rows.Count, "B").End(xlUp).Row
w = 7
For r = 2 To lr
If Range("I" & r).Value = "White" Then
Sh2.Cells(w, 5).Value = Sh1.Cells(r, 2).Value
Sh2.Cells(w, 6).Value = Sh1.Cells(r, 3).Value
w = w + 1
End If
Next r
py = 79
For r = 2 To lr
If Range("I" & r).Value = "Pro Yellow" Then
Sh2.Cells(py, 5).Value = Sh1.Cells(r, 2).Value
Sh2.Cells(py, 6).Value = Sh1.Cells(r, 3).Value
py = py + 1
End If
Next r
Sh2.Select
End Sub
There's a couple of problems it looks like you will encounter. You are defining w and py as integers but you said that you could have a large number of people in each category and I'm assuming those numbers will change so you could end up with a problem by specifying which row to begin with.
This will allow you to put in your 23 belt colors in as an Array (Changes the Belts(2) to Belts(23) and fill in the colors) and then it will format your second sheet according to how many you have in each color based on the first page.
I am assuming you have a header on the second sheet in the first six rows. You may need to update the Header variable to accurately reference that range, as this will insert a page break then copy that header repeatedly for as long as necessary:
Sub ADULTClearAndPaste()
Dim Belts(2) As String
Belts(1) = "White"
Belts(2) = "Pro Yellow"
Dim NewRow As Long
Dim RowCounter As Long
Dim Item As Range
Dim Header As Range
Dim Sht1 As Worksheet
Dim Sht2 As Worksheet
Set Sht1 = ThisWorkbook.Worksheets("ADULT members to cut & past")
Set Sht2 = ThisWorkbook.Worksheets("ADULT Sign On Sheet")
'Specify Header Range
Set Header = Sht2.Range("A1:F6")
NewRow = 7
For i = 1 To UBound(Belts)
'This creates a new header/page for the next belt color
If NewRow <> 7 Then
Sht2.Rows(NewRow).PageBreak = xlPageBreakManual
Sht2.Range(Sht2.Cells((NewRow), 1), Sht2.Cells((NewRow + 5), 6)).Value = Header.Value
NewRow = NewRow + 6
End If
'This will reference which color is being processed,
'I put it in there for reference but I figured you would update it
Sht2.Range("A" & NewRow).Value = Belts(i)
RowCounter = 0
For Each Item In Sht1.Range("I1:I" & Sht1.UsedRange.Rows.Count)
If Item.Value = Belts(i) Then
Sht2.Cells(NewRow, 5).Value = Item.Offset(0, 1).Value
Sht2.Cells(NewRow, 6).Value = Item.Offset(0, 2).Value
NewRow = NewRow + 1
RowCounter = RowCounter + 1
If RowCounter = 30 Then
'When you hit 30 lines the counter resets and a new header is added
Sht2.Rows(NewRow).PageBreak = xlPageBreakManual
Sht2.Range(Sht2.Cells((NewRow), 1), Sht2.Cells((NewRow + 5), 6)).Value = Header.Value
NewRow = NewRow + 6
RowCounter = 0
End If
End If
Next Item
Next i
Sht2.Select
End Sub
I am new to VBA and to this forum. I have a table with dates as the first column (x column) and 12 columns of data pertaining to the data (y values). I am trying to plot the data in a simple xlLine chart. Only few selected columns are to be plotted for y values. The columns are selected using a combo box at the top of the column. The number of rows are variable.
I am using this code but this is not working. Can someone kindly let me know what is wrong and fix it? Appreciate any help. Thanks in advance.
Sub drawchart1()
'
' drawchart1 Macro
'
'
Dim i As Integer
Dim j As Integer
Dim n As Integer
' finding the number of rows
j = Range("Charts!A1").Offset(Sheet1.Rows.Count - 1, 0).End(xlUp).Row
' selecting some range and adding a chart which is then modified.(not sure this is the correct method.)
Range("A10:C15").Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlLine
i = 2
n = 2
' Cells (9,1) contains the value "Date". Defining the X Axis values
ActiveChart.SeriesCollection(1).Name = Sheets("Charts").Cells(9, 1).Value
ActiveChart.SeriesCollection(1).XValues = "=Charts!R10C1:R" & j & "C1"
Do While i < 14
' Cells(8,i) contain the results of combo box - true or false.
' Cells(9,i) contain the names of the series
If Cells(8, i).Value = True Then
ActiveChart.SeriesCollection(n).Name = Sheets("Charts").Cells(9, i).Value
ActiveChart.SeriesCollection(n).Values = "=Charts!R10C" & i & ":R" & j & "C" & i
n = n + 1
i = i + 1
Else
i = i + 1
End If
Loop
End Sub
Hi Again,
Since my columns would not exceed 14 (i.e. not large), I used the following "brute force" technique and it worked fine. I would still love to learn how to do it without using the "brute force" technique. Thanks in advance.
Sub drawchart()
Dim j As Integer
Dim Chartstring As String
j = Range("Charts!A1").Offset(Sheet1.Rows.Count - 1, 0).End(xlUp).Row
Chartstring = "A9:A" & j
If Cells(8, 2).Value = True Then
Chartstring = Chartstring & ", B9:B" & j
Else
Chartstring = Chartstring
End If
If Cells(8, 3).Value = True Then
Chartstring = Chartstring & ", C9:C" & j
Else
Chartstring = Chartstring
End If
' And similarly added code for each of the 14 columns
' And finally fed the chartstring into the "Source"
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlLine
ActiveChart.SetSourceData Source:=Range(Chartstring)
End Sub
Probably you're not watching any more. Here's an alternative approach.
Sub DrawChart1()
Dim i As Long
Dim j As Long
Dim ws As Worksheet
Dim rCht As Range, rYVals As Range
Dim cht As Chart
' finding the number of rows
Set ws = Worksheets("Charts")
j = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
' start with X values (row 10 to j), include header row (row 9)
Set rCht = ws.Range(ws.Cells(9, 1), ws.Cells(j, 1))
' add column of Y values if row 8 of column is TRUE
For i = 2 To 14
If ws.Cells(8, i).Value Then
Set rYVals = ws.Range(ws.Cells(9, i), ws.Cells(j, i))
Set rCht = Union(rCht, rYVals)
End If
Next
' if we've had any Y values, insert chart, using range we've built up
If Not rYVals Is Nothing Then
Set cht = ws.Shapes.AddChart(xlLine).Chart
cht.SetSourceData Source:=rCht, PlotBy:=xlColumns
End If
End Sub