VBA How to do a recurring cycle - excel

I have code that generates stickers, I wrote it this way below, so for 15 stickers. Can it be done with a loop for easier code writing because I have to do it up to 100 stickers? I have currently written it for 15 stickers and it works by changing the cell names manually because they are different.
Thank you
Code is:
Sheets("Helper").Range("A1:Z50").Clear
Sheets("DUT Sticker").Range("A8:C100").Clear
If Sheets("Helper").Range("A1").Value <> "" Then
Sheets("DUT Sticker").Range("A3:C7").Copy
Sheets("DUT Sticker").Range("A8").PasteSpecial Paste:=xlPasteAll
Sheets("DUT Sticker").Range("A8").Value = Sheets("DUT Sticker").Range("A3") + 1
Sheets("DUT Sticker").Select
ActiveSheet.Shapes.Range(Array("Picture 3")).Select
Selection.Copy
Sheets("DUT Sticker").Range("B8").Select
ActiveSheet.Paste
Selection.ShapeRange.IncrementLeft 2
Selection.ShapeRange.IncrementTop 4
Sheets("Helper").Range("A1").Copy
Sheets("DUT Sticker").Range("B8").PasteSpecial Paste:=xlPasteAll
Sheets("DUT Sticker").Range("B9") = Sheets("Helper").Range("B2")
Sheets("DUT Sticker").Range("B10") = Sheets("Helper").Range("J2")
Sheets("DUT Sticker").Range("B11") = Sheets("Helper").Range("K2")
Sheets("DUT Sticker").Range("C9").Formula = "=IF(Helper!R[-7]="""",""SPARE"",""SS ""&Helper!R[-7]&""#""&Helper!R[-7]C[1])"
Sheets("DUT Sticker").Range("C10") = Sheets("Sample Recording Form").Range("F5")
Sheets("DUT Sticker").Range("C12").Formula = "S/N: " & Sheets("Helper").Range("I2")
Sheets("DUT Sticker").PageSetup.PrintArea = "$B$3:$C$12"
End If
If Sheets("Helper").Range("A2").Value <> "" Then
Sheets("DUT Sticker").Range("A3:C7").Copy
Sheets("DUT Sticker").Range("A13").PasteSpecial Paste:=xlPasteAll
Sheets("DUT Sticker").Range("A13").Value = Sheets("DUT Sticker").Range("A8") + 1
Sheets("DUT Sticker").Select
ActiveSheet.Shapes.Range(Array("Picture 3")).Select
Selection.Copy
Sheets("DUT Sticker").Range("B13").Select
ActiveSheet.Paste
Selection.ShapeRange.IncrementLeft 2
Selection.ShapeRange.IncrementTop 4
Sheets("Helper").Range("A2").Copy
Sheets("DUT Sticker").Range("B13").PasteSpecial Paste:=xlPasteAll
Sheets("DUT Sticker").Range("B14") = Sheets("Helper").Range("B3")
Sheets("DUT Sticker").Range("B15") = Sheets("Helper").Range("J3")
Sheets("DUT Sticker").Range("B16") = Sheets("Helper").Range("K3")
Sheets("DUT Sticker").Range("C14").Formula = "=IF(Helper!R[-11]="""",""SPARE"",""SS ""&Helper!R[-11]&""#""&Helper!R[-11]C[1])"
Sheets("DUT Sticker").Range("C15") = Sheets("Sample Recording Form").Range("F5")
Sheets("DUT Sticker").Range("C17").Formula = "S/N: " & Sheets("Helper").Range("I3")
Sheets("DUT Sticker").PageSetup.PrintArea = "$B$3:$C$17"
End If
end sub

There are different ways to access another cell:
i = 15
Cell_A15_Value = Range("A" & i).Value
Cell_A15_Value = Range("A1").OffSet(14,0).Value
(Obviously, as you start by row 1, you need to add 14 to get to cell A15.

Please, try the next code. It is not tested, of course. I only tried following your code logic, adapting it to avoid selections and working faster. I would suggest you to try it line by line (pressing F8) and see what it does. I shouldn't be impossible to miss something in terms of variables incrementation:
Sub MakeStickers()
Dim shH As Worksheet, shD As Worksheet, lastRH As Long, i As Long, k As Long, J As Long, M As Long
Dim sh As Shape, constVal
constVal = Sheets("Sample Recording Form").Range("F5").value
k = 8: J = 3: M = 2
Set shH = Sheets("Helper")
lastRH = shH.Range("A" & shH.rows.count).End(xlUp).row
Set shD = Sheets("DUT Sticker")
shD.Range("A8:C100").Clear
'Sheets("Helper").Range("A1:Z50").Clear 'clearing this sheet, the iteration will never find a range in A:A column <> ""
For i = 1 To lastRH
If shH.Range("A" & i).value <> "" Then
shD.Range("A3:C7").Copy shD.Range("A" & k)
shD.Range("A" & k).value = shD.Range("A" & J) + 1
shD.Shapes("Picture 3").Copy: shD.Paste
Set sh = shD.Shapes(shD.Shapes.count)
sh.top = shD.Range("B" & k).top
sh.left = shD.Range("B" & k).left
shD.Range("B" & k).value = shH.Range("A" & i).value
shD.Range("B" & k + 1).value = Sheets("Helper").Range("B" & M).value
shD.Range("B" & k + 2).value = Sheets("Helper").Range("J" & M).value
shD.Range("B" & k + 3).value = Sheets("Helper").Range("K" & M)
shD.Range("C" & k + 1).Formula = "=IF(Helper!R[-" & k - 1 & "]="""",""SPARE"",""SS ""&Helper!R[-" & k - 1 & "]&""#""&Helper!R[-" & k - 1 & "]C[1])"
shD.Range("C" & k + 2).value = constVal
shD.Range("C" & k + 4).value = "S/N: " & Sheets("Helper").Range("I" & M).value
Sheets("DUT Sticker").PageSetup.PrintArea = "$B$3:$C$" & k + 4
'reset variables:
k = k + 5: M = M + 1: J = J + 5
End If
Next i
End Sub
If not confidential, can you share the workbook in discussion? I will try adapting the above code according to its behavior on the real workbook...

Related

Selecting and deselecting specific boxes

I'm trying to create a catalog containing parts from different brands and machines. As I previously asked, I tried to loop through the catalog to use diferent worksheets and not comprise everything into one, but every useful tip that was kindly given to me was, quite unsuccesfully, applied by me.
The way the code is written is to pull information from a database based on a few selection boxes on a customizing menu, as in the picture attached. The selection boxes are set to change from "selected" to "deselected" from a font when clicked on.
However, the database is going to contain too many machines to search on the list by name, and I'm trying to figure out a way to deselect all of the other boxes when a specific one is selected.
For example, if the selection box for "CATERPILLAR" is selected, I want the macro to automatically deselect all of the other boxes that aren't linked in the database, or in the catalog, every machine that isn't from the brand "Caterpillar" by changing the "empty box" character into the "checked box" character.
The font used was "Wingdings" and the empty box is character 168, while the checked box is 254.
Is there any way I can do that? Maybe if I create another variable other than "LIST", "TEXT" or "NUMBER" to show only the ones under the category "LIST" related? Because "Modelo" and "Marca" are both under "LIST". Been fiddling with this one for a while! Code of the customizing part follows:
Dim CustRow As Long, ProdCol As Long, ProdRow As Long, LastProdRow As Long, LastResultRow As Long
Dim DataType As String
Dim ItemShp As Shape
Sub Customize_Open()
With Sheet1
'limpar grupos menos amostra
For Each ItemShp In .Shapes
On Error Resume Next
If InStr(ItemShp.Name, "Picture") <> Empty Then ItemShp.Delete
If InStr(ItemShp.Name, "ItemGrp") <> Empty Then ItemShp.Delete
On Error GoTo 0
Next ItemShp
On Error Resume Next
.Shapes("SampleGrp").Visible = msoCTrue
.Shapes("SampleGrp").Ungroup
On Error GoTo 0
'colocar em free floating
For Each ItemShp In .Shapes
If InStr(ItemShp.Name, "Sample") > 0 Then
ItemShp.Placement = xlFreeFloating
ItemShp.Visible = msoCTrue
End If
Next ItemShp
.Shapes("CloseCustBtn").Visible = msoCTrue
.Shapes("ResetBtn").Visible = msoCTrue
.Shapes("LabelTemplate").Visible = msoCTrue
.Shapes("OpenCustBtn").Visible = msoFalse
.Range("C:F").EntireColumn.Hidden = False
End With
End Sub
Sub Customize_Close()
With Sheet1
On Error Resume Next
.Shapes("SampleGrp").Placement = xlFreeFloating
.Shapes("SampleGrp").Visible = msoFalse
On Error GoTo 0
.Shapes("CloseCustBtn").Visible = msoFalse
.Shapes("LabelTemplate").Visible = msoFalse
.Shapes("ResetBtn").Visible = msoFalse
.Shapes("OpenCustBtn").Visible = msoCTrue
.Range("C:F").EntireColumn.Hidden = True
End With
End Sub
Sub Customize_Refresh()
LastProdRow = Sheet2.Range("A99999").End(xlUp).Row 'ultima linha
With Sheet1
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
.Range("A8:F999").ClearContents
.Range("D5:F999").Characters.Font.Name = "Calibri"
.Range("10:999").EntireRow.Hidden = False
Sheet2.Range("AA4:AS999").ClearContents 'limpar critérios e resultados
'definir campos de informação
Range("A8").Value = 9
.Range("C8").Value = Chr(117)
.Range("D8").Value = "CAMPOS INFORMAÇÃO"
.Range("D9:D17").Value = Chr(168) 'caixinha desmarcada
.Range("D9:D17").Characters.Font.Name = "Wingdings"
.Range("E9:E17").Value = Sheet2.Range("l3:l11").Value
.Range("9:17").EntireRow.Hidden = True
'definir filtros
.Range("D18").Value = "FILTROS"
CustRow = 19
For ProdCol = 1 To 8
DataType = Sheet2.Cells(2, ProdCol).Value
Select Case DataType
Case Is = "TEXT"
.Range("D" & CustRow).Value = Sheet2.Cells(3, ProdCol).Value 'cabeçalho
Case Is = "LIST"
On Error Resume Next
Sheet2.Names("Criteria").Delete
Sheet2.Names("Extract").Delete
On Error GoTo 0
Sheet2.Range("A3:H" & LastProdRow).AdvancedFilter xlFilterCopy, , CopyToRange:=Sheet2.Cells(3, ProdCol + 14), Unique:=True
LastResultRow = Sheet2.Cells(9999, ProdCol + 14).End(xlUp).Row 'ultima linha de dado unico
If LastResultRow < 4 Then GoTo NoResult
.Range("A" & CustRow).Value = LastResultRow - 3 '# de itens
.Range("B" & CustRow + 1 & ":B" & CustRow + LastResultRow - 3).Value = ProdCol 'coluna peça
.Range("C" & CustRow).Value = Chr(117) 'triangulo pra direita
.Range("D" & CustRow).Value = Sheet2.Cells(3, ProdCol + 14).Value
.Range("A" & CustRow + 1 & ":A" & CustRow + LastResultRow - 3).Value = CustRow + 1 'linha
.Range("D" & CustRow + 1 & ":D" & CustRow + LastResultRow - 3).Value = Chr(254) 'caixinha marcada
.Range("D" & CustRow + 1 & ":D" & CustRow + LastResultRow - 3).Font.Name = "Wingdings"
.Range("E" & CustRow + 1 & ":E" & CustRow + LastResultRow - 3).Value = Sheet2.Range(Sheet2.Cells(4, ProdCol + 14), Sheet2.Cells(LastResultRow, ProdCol + 14)).Value 'trazer resultados
.Range(CustRow + 1 & ":" & CustRow + LastResultRow - 3).EntireRow.Hidden = True
CustRow = CustRow + LastResultRow - 2
Case Is = "NUMBER"
.Range("A" & CustRow).Value = 2
.Range("B" & CustRow + 1 & ":B" & CustRow + 2).Value = ProdCol
.Range("C" & CustRow).Value = Chr(117)
.Range("D" & CustRow).Value = Sheet2.Cells(3, ProdCol).Value
.Range("D" & CustRow + 1).Value = ">="
.Range("D" & CustRow + 2).Value = "<="
.Range(CustRow + 1 & ":" & CustRow + 2).EntireRow.Hidden = True
CustRow = CustRow + 3
NoResult:
End Select
Next ProdCol
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End With
End Sub

How to use vba vlookup formula from two sheets?

I have two sheets first one called Sheet8 is for the Main table that can be used by the Data Entry Form to enter the data in that table, and the second called Sheet9 that includes the table for the vlookup. What I want is in the data entry user form as soon as I enter the Name the Discipline is created automatically based on that name.
Screenshot of the Data Entry for the Main table in sheet8
Screenshot of the sheet9 Table
The code for Save Button
Private Sub btnSave_Click()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Sheet8")
Dim n As Long
n = sh.Range("A" & Application.Rows.Count).End(xlUp).Row
sh.Unprotect "1234"
sh.Range("A" & n + 1).Value = Me.txtDate.Value
sh.Range("B" & n + 1).Value = Me.txtName.Value
sh.Range("C" & n + 1).Value = Me.txtProjNo.Value
sh.Range("D" & n + 1).Value = Me.txtProjTitle.Value
sh.Range("E" & n + 1).Value = Me.txtBVEntity.Value
sh.Range("F" & n + 1).Value = Me.txtZIG.Value
sh.Range("G" & n + 1).Value = Me.txtSpenthrs.Value
sh.Range("H" & n + 1).Value = Me.comboCategory.Value
sh.Range("I" & n + 1).Value = Me.txtDiscipline.Value
sh.Range("J" & n + 1).Value = Me.txtSCV.Value
sh.Range("K" & n + 1).Value = Me.txtTotSCV.Value
sh.Range("L" & n + 1).Value = Me.txtCotMER.Value
sh.Range("M" & n + 1).Value = Me.txtBudgethrs.Value
sh.Range("N" & n + 1).Value = Me.txtBudget.Value
sh.Range("O" & n + 1).Value = Me.txtProgress.Value
sh.Range("P" & n + 1).Value = Me.txtEndDate.Value
sh.Protect "1234"
The code for the Name textbox
Private Sub txtName_AfterUpdate()
If WorksheetFunction.CountIf(Sheet9.Range("C:D"), Me.txtName.Value) = 0 Then
MsgBox "This Name is Invalid."
Me.txtName.Value = ""
Exit Sub
End If
With Me
.txtDiscipline = Application.WorksheetFunction.VLookup(Me.txtName, Sheet9.Range("Lookup"), 4, 0)
End With
End Sub

I'm trying to find where there is a "1" and to find the next "1" in a range

I have a small project I've been working on where I have a range of cells that have a status of either 1 or 0 for online and offline. What is the best method to look in a range of cells and go from a "1" to the next "1" and take the date and do some simple subtraction from the original date of offline to the next. I am assuming that -1 of that value will be the up-time of the equipment. Below is a copy of the code I've used and the layout of the excel worksheet that it pertains to.
If there are any better methods I am all ears. Still pretty new to VBA and I'm sure that what I wrote is not best practice.
Sub StatsRunner()
Dim weekStartDate As Date
Dim weekEndDate As Date
Dim monthEndDate As Date
Dim monthStartDate As Date
Dim augustStartDate As Date
Dim today As Date
Dim Rng As Range
Dim nextOnline As String
Dim nextOffline As String
weekStartDate = Now - 7
weekEndDate = Now + 1
monthEndDate = Now
monthStartDate = Now - 30
'43678 corresponds to the numeric value for the data 8/1/2019
janStartDate = 43831
today = Now
rowHolder = 6
statsFirstRow = Worksheets("Stats").Cells(Rows.Count, 1).End(xlUp).Row
Worksheets("Stats").Activate
ActiveSheet.Range("E6:R2000").ClearContents
For i = 6 To statsFirstRow
If Worksheets("Stats").Cells(i, 1).Value >= weekStartDate _
And Worksheets("Stats").Cells(i, 1).Value <= weekEndDate Then
Worksheets("Stats").Range("A" & i & ":B" & i).Copy
ActiveSheet.Range("E" & rowHolder & ":F" & rowHolder).Select
ActiveSheet.Paste
rowHolder = rowHolder + 1
End If
Next
'This is for a single instance of item in a column
weekEndRow = Worksheets("Stats").Cells(Rows.Count, 6).End(xlUp).Row
If Worksheets("Stats").Range("F" & weekEndRow).Value = 0 And weekEndRow = 6 Then
ActiveSheet.Range("P6").Value = 0
ElseIf Worksheets("Stats").Range("F" & weekEndRow).Value = 1 And weekEndRow = 6 Then
ActiveSheet.Range("P6").Value = 1
End If
'This next section tries to find the differences in each of the rows
weekFirstRow = Worksheets("Stats").Cells(Rows.Count, 6).End(xlUp).Row
For e = 6 To weekFirstRow
'Used to hold the column for the weeks section where there will be integer addition/subtraction
colHold = 6
'Reintializes 'c' for a totals variable
c = 0
a = ActiveSheet.Cells(e, 5).Value
If Application.WorksheetFunction.IsNumber(ActiveSheet.Range("F" & e + 1).Value) = True Then
b = ActiveSheet.Cells(e + 1, 5).Value
c = b - a
ActiveSheet.Range("L" & e).Value = c
Else:
b = Now
c = b - a
ActiveSheet.Range("L" & e).Value = c
End If
End If
' Else:
' ActiveSheet.Range("L6").Value = 0
' ActiveSheet.Range("P6").Value = 0
'
' End If
Next
'------------MONTH ITERATION-----------------------------------------
rowHolder = 6
For i = 6 To statsFirstRow
If Worksheets("Stats").Cells(i, 1).Value >= monthStartDate _
And Worksheets("Stats").Cells(i, 1).Value <= monthEndDate Then
Worksheets("Stats").Range("A" & i & ":B" & i).Copy
ActiveSheet.Range("G" & rowHolder & ":H" & rowHolder).Select
ActiveSheet.Paste
rowHolder = rowHolder + 1
End If
Next
monthFirstRow = Worksheets("Stats").Cells(Rows.Count, 8).End(xlUp).Row
For f = 6 To monthFirstRow
c = 0
If monthFirstRow > 6 And Worksheets("Stats").Cells(6, 8) = 1 Then
If Worksheets("Stats").Cells(f, 8).Value = 1 Then
a = ActiveSheet.Cells(f, 7).Value
If Application.WorksheetFunction.IsNumber(ActiveSheet.Range("H" & f + 1).Value) = True Then
b = ActiveSheet.Cells(f + 1, 7).Value
c = b - a
ActiveSheet.Range("M" & f).Value = c
Else:
b = Now
c = b - a
ActiveSheet.Range("M" & f + 1).Value = c
End If
End If
Else
ActiveSheet.Range("M6").Value = 0
ActiveSheet.Range("Q6").Value = 0
End If
Next
'Use DateDiff to find the total hrs of availability from Jan 1st to current date.
rowHolder = 6
For i = 6 To statsFirstRow
If Worksheets("Stats").Cells(i, 1).Value >= janStartDate _
And Worksheets("Stats").Cells(i, 1).Value <= today Then
Worksheets("Stats").Range("A" & i & ":B" & i).Copy
ActiveSheet.Range("I" & rowHolder & ":J" & rowHolder).Select
ActiveSheet.Paste
rowHolder = rowHolder + 1
End If
Next
janFirstRow = Worksheets("Stats").Cells(Rows.Count, 10).End(xlUp).Row
For g = 6 To janFirstRow
c = 0
If janFirstRow > 6 And Worksheets("Stats").Cells(6, 10) = 1 Then
If Worksheets("Stats").Cells(g, 10).Value = 1 Then
a = ActiveSheet.Cells(g, 9).Value
If Application.WorksheetFunction.IsNumber(ActiveSheet.Range("J" & g + 1).Value) = True Then
b = ActiveSheet.Cells(g + 1, 9).Value
c = b - a
ActiveSheet.Range("N" & g).Value = c
Else:
b = Now
c = b - a
ActiveSheet.Range("N" & g + 1).Value = c
End If
End If
Else
ActiveSheet.Range("N6").Value = 0
ActiveSheet.Range("R6").Value = 0
End If
Next
End Sub

Excel VBA Paste error when applying style to cell

I'm seeking some assistance. I have a code that does what I need and works pretty fine, but I want to make it do some more, and thats when it breaks.
Here is the code, a bit messy I know:
Sub AgainstAbstain()
Application.ScreenUpdating = False
'Stating variables
Dim Abstain As String
Abstain = "Abstain"
Dim Against As String
Against = "Against"
Dim C11 As Variant
'Enter amount of votable items
Dim e As Byte 'number of agenda items
e = InputBox("Number of votable items in Agenda?")
'Create Necessary sheets
On Error Resume Next
Sheets("Abstain").Delete
'Sheets("Against").Delete
On Error GoTo 0
ActiveWorkbook.Sheets.Add After:=Worksheets(Worksheets.Count)
'ActiveWorkbook.Sheets.Add After:=Worksheets(Worksheets.Count)
ActiveWorkbook.Sheets(2).Name = "Abstain"
'ActiveWorkbook.Sheets(3).Name = "Against"
'Change zoom level of sheets
Sheets(2).Activate
ActiveWindow.Zoom = 85
'Sheets(3).Activate
'ActiveWindow.Zoom = 85
Sheets(1).Activate
'For better copying of cells
Cells.WrapText = False
'To count spaces
Dim j As Integer
j = 1
Dim k As Integer
k = 1
Dim c As Integer
c = 3 '
'Main filter and copy
For i = 1 To e
Worksheets(1).Cells(11, c).Select
C11 = ActiveCell.Value
'Range("A11:C11").Select
Range(Cells(11, 1), Cells(11, c)).Select
Selection.AutoFilter
ActiveSheet.Range("C:C").AutoFilter Field:=c, Criteria1:="ABSTAIN"
'Amount of items visible after filter
Dim x As Integer
x = Application.Subtotal(3, Columns("A")) - 19
'MsgBox x
If x > 0 Then
ActiveSheet.AutoFilter.Range.Offset(1).Copy
Sheets("ABSTAIN").Activate
' Range("A" & j).Select
' Range("A" & j).Font.Bold = True
' Range("A" & j).Font.Underline = True
Range("A" & j).Value = C11 & ") " & Abstain
j = j + 2
' Range("A" & j).Select
Range("A" & j).Value = "Beneficial owner:"
'Range("A" & j).Font.Bold = True
Range("B" & j).Value = "Number of shares:"
'Range("A" & j).Font.Bold = True
j = j + 1
Sheets(2).Range("A" & j).PasteSpecial
' Range("A" & j).Select
' ActiveSheet.Paste
j = j + x
Range("A" & j).Value = "Sum"
Range("A" & j).Font.Bold = True
Range("A" & j).Interior.Color = RGB(255, 204, 153)
Range("B" & j).Font.Bold = True
Range("B" & j).Interior.Color = RGB(255, 204, 153)
j = j + 3
Columns(3).EntireColumn.Delete
Err.Clear
Sheets(1).Activate
Worksheets(1).Columns(c).Hidden = True
c = c + 1
Cells.AutoFilter
Else: Cells.AutoFilter
Worksheets(1).Columns(c).Hidden = True
c = c + 1
End If
Next i
Cells.EntireColumn.Hidden = False
c = 3
For i = 1 To e
Worksheets(1).Cells(11, c).Select
C11 = ActiveCell.Value
'Range("A11:C11").Select
Range(Cells(11, 1), Cells(11, c)).Select
Selection.AutoFilter
ActiveSheet.Range("C:C").AutoFilter Field:=c, Criteria1:="AGAINST"
'Amount of items visible after filter
Dim y As Integer
y = Application.Subtotal(3, Columns("A")) - 19
'MsgBox y
If y > 0 Then
ActiveSheet.AutoFilter.Range.Offset(1).Copy
Sheets("Abstain").Activate
' Range("A" & j).Select
Range("A" & j).Value = C11 & ") " & Abstain
j = j + 2
' Range("A" & j).Select
Range("A" & j).Value = "Beneficial owner:"
Range("B" & j).Value = "Number of shares:"
j = j + 1
Sheets(2).Range("A" & j).PasteSpecial
' Range("A" & j).Select
' ActiveSheet.Paste
j = j + y
Range("A" & j).Value = "Sum"
Range("A" & j).Font.Bold = True
Range("A" & j).Interior.Color = RGB(255, 153, 204)
Range("B" & j).Font.Bold = True
Range("B" & j).Interior.Color = RGB(255, 153, 204)
j = j + 3
Columns(3).EntireColumn.Delete
Err.Clear
Sheets(1).Activate
Worksheets(1).Columns(c).Hidden = True
c = c + 1
Cells.AutoFilter
Else: Cells.AutoFilter
Worksheets(1).Columns(c).Hidden = True
c = c + 1
End If
'If y > 0 Then
'ActiveSheet.AutoFilter.Range.Offset(1).Copy
' Sheets("AGAINST").Activate
' Range("A" & k).Select
' Range("A" & k).Value = C11 & ") " & Against
' k = k + 2
' Range("A" & k).Select
' Range("A" & k).Value = "Beneficial owner:"
' k = k + 1
' Range("A" & k).Select
' ActiveSheet.Paste
' k = k + y
' Range("A" & k).Value = "Sum"
' k = k + 3
' Columns(3).EntireColumn.Delete
' Err.Clear
' Sheets(1).Activate
' Cells.AutoFilter
' 'Columns(3).EntireColumn.Delete
' Worksheets(1).Columns(c).Hidden = True
' c = c + 1
'Else: Cells.AutoFilter
' 'Columns(3).EntireColumn.Delete
' Worksheets(1).Columns(c).Hidden = True
' c = c + 1
'End If
Next i
Sheets(2).Activate
For Each NumRange In Columns("B").SpecialCells(xlConstants, xlNumbers).Areas
SumAddr = NumRange.Address(False, False)
NumRange.Offset(NumRange.Count, 0).Resize(1, 1).Formula = "=SUM(" & SumAddr & ")"
c = NumRange.Count
Next NumRange
NoData:
'Sheets(2).Select
Columns("A:B").AutoFit
Sheets(1).Activate
Cells.EntireColumn.Hidden = False
Application.ScreenUpdating = True
End Sub
It filters and moves data just fine. But when i try to activate this part
' Range("A" & j).Font.Bold = True
' Range("A" & j).Font.Underline = True
It gives me this error
Run-time error '1004':
PasteSpecial method of Range class failed. In fact, if I try to activate any style change before the paste i get this error.
And highlights this area
Sheets(2).Range("A" & j).PasteSpecial
I just don't get.
After the .Copy method you need to immediately paste the results. Doing anything else will empty the copy buffer, so this will work:
ActiveSheet.Range("A1").Copy
ActiveSheet.Range("A2").PasteSpecial
ActiveSheet.Range("A1").Font.Size = 10
But this won't
ActiveSheet.Range("A1").Copy
ActiveSheet.Range("A1").Font.Size = 10
ActiveSheet.Range("A2").PasteSpecial

Move records from repeating rows to columns with Excel and VBA

I have about 70,000 rows of data and two columns (Field,Data) which repeats every 50-100 rows (Record). I would like to write something that searches for the values based on "Field Text" (I'm only interested in about 5 fields) and paste the value into a new worksheet with rows as records and columns as fields. The first field I'm searching for will need to indicate new row/record.
My first attempt at this failed, and I've found little help on the forums. Although it looks like maybe a pivot table could do this?
Visual of what I'd like to do:
Example
EDIT:
I got the result I wanted but my do until "END" isnt catching. I do have "END" in the last cell of the data. Also, I'm sure there is a more efficient way to do this, any advice? Thanks!
Sub TracePull()
Dim i As Long
Dim j As Long
i = 1
j = 1
ActiveWorkbook.Sheets("Trace").Range("A1").Select
Do Until Range("A" & i) = "END"
Do Until ActiveCell = "OTDRFilename"
i = i + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Activate
Loop
If ActiveCell = "OTDRFilename" Then
ActiveWorkbook.Sheets("Trace").Range("B" & i).Copy
ActiveWorkbook.Sheets("Sheet1").Range("A" & j + 1).PasteSpecial Paste:=xlValue
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
i = i + 1
j = j + 1
'Else
' i = i + 1
End If
Range("A" & i).Select
Do Until ActiveCell = "OTDRSpan length"
i = i + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Activate
Loop
If ActiveCell = "OTDRSpan length" Then
ActiveWorkbook.Sheets("Trace").Range("B" & i).Copy
ActiveWorkbook.Sheets("Sheet1").Range("B" & j).PasteSpecial Paste:=xlValue
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
i = i + 1
End If
Range("A" & i).Select
Do Until ActiveCell = "OTDRSpan loss"
i = i + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Activate
Loop
If ActiveCell = "OTDRSpan loss" Then
ActiveWorkbook.Sheets("Trace").Range("B" & i).Copy
ActiveWorkbook.Sheets("Sheet1").Range("C" & j).PasteSpecial Paste:=xlValue
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
i = i + 1
End If
Range("A" & i).Select
Do Until ActiveCell = "OTDRAverage loss"
i = i + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Activate
Loop
If ActiveCell = "OTDRAverage loss" Then
ActiveWorkbook.Sheets("Trace").Range("B" & i).Copy
ActiveWorkbook.Sheets("Sheet1").Range("D" & j).PasteSpecial Paste:=xlValue
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
i = i + 1
End If
Range("A" & i).Select
Do Until ActiveCell = "OTDRSpan ORL"
i = i + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Activate
Loop
If ActiveCell = "OTDRSpan ORL" Then
ActiveWorkbook.Sheets("Trace").Range("B" & i).Copy
ActiveWorkbook.Sheets("Sheet1").Range("E" & j).PasteSpecial Paste:=xlValue
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
i = i + 1
End If
Range("A" & i).Select
Do Until ActiveCell = "OTDRWavelength"
i = i + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Activate
Loop
If ActiveCell = "OTDRWavelength" Then
ActiveWorkbook.Sheets("Trace").Range("B" & i).Copy
ActiveWorkbook.Sheets("Sheet1").Range("F" & j).PasteSpecial Paste:=xlValue
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
i = i + 1
End If
i = i + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
Range("A" & i).Select
Loop
End Sub
I think your main problem is incrementing i twice (which passes 'END' cell) at the bottom of your code.
One way to make it more readable is by using select case. Also, you can speed up the code by assigning the value directly (without copy paste) and by turning off screen updating since you have 70,000 rows. Those things will improve performance considerably.
Sub TracePull()
ScreenUpdating = False
Dim i As Long
Dim j As Long
i = 1
j = 1
ActiveWorkbook.Sheets("Trace").Range("A1").Select
Do Until Range("A" & i) = "END"
Select Case ActiveCell.Text
Case "OTDRFilename"
ActiveWorkbook.Sheets("Sheet1").Range("A" & j + 1).Value = ActiveWorkbook.Sheets("Trace").Range("B" & i).Value
Case "OTDRSpan length"
ActiveWorkbook.Sheets("Sheet1").Range("B" & j).Value = ActiveWorkbook.Sheets("Trace").Range("B" & i).Value
Case "OTDRSpan loss"
ActiveWorkbook.Sheets("Sheet1").Range("C" & j).Value = ActiveWorkbook.Sheets("Trace").Range("B" & i).Value
Case "OTDRAverage loss"
ActiveWorkbook.Sheets("Sheet1").Range("D" & j).Value = ActiveWorkbook.Sheets("Trace").Range("B" & i).Value
Case "OTDRSpan ORL"
ActiveWorkbook.Sheets("Sheet1").Range("E" & j).Value = ActiveWorkbook.Sheets("Trace").Range("B" & i).Value
Case "OTDRWavelength"
ActiveWorkbook.Sheets("Sheet1").Range("F" & j).Value = ActiveWorkbook.Sheets("Trace").Range("B" & i).Value
End Select
i = i + 1
j = j + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
Loop
ScreenUpdating = True
End Sub
You might also want to consider defining the workbook and worksheet rather than relying upon activesheet. In addition, the code with break if someone forget to have 'END' entered in the last cell, so maybe just get last cell used instead of looking for 'END'
Dim wb As Workbook
Dim wskA As Worksheet
Dim wskB As Worksheet
wb = ActiveWorkbook
wskA = wb.Sheets("Trace")
wskB = wb.Sheets("Sheet1")
numofrows = wskA.Offset(wskA.Rows.Count - 1, 0).End(xlUp).Row
wskA.Range("A1").Select
Do Until i > numofrows
Select Case ActiveCell.Text
Case "OTDRFilename"
wskB.Range("A" & j + 1).Value = wskA.Range("B" & i).Value

Resources