I need this macro to hide certain columns when the value of $A$5 is equal to "Company 2". The query below hides the columns successfully but doesn't executed the print loop. What's the correct way to set this up?
Sub PrintAll()
Dim BrokerCell As Range
Dim TotalCell As Range
Dim Rng As Range
Dim Wks As Worksheet
Set Wks = Worksheets("PRINT PAGE")
If Range("$A$5").Value = "Company 1" Then
Set Rng = ThisWorkbook.Names("Company1").RefersToRange
ElseIf Range("$A$5").Value = "Company 2" Then
Set Rng = ThisWorkbook.Names("Company2").RefersToRange
Else: Set Rng = ThisWorkbook.Names("Company3").RefersToRange
End If
If Range("$A$5").Value = "Company 2" Then
Columns("M:O").Select
Selection.EntireColumn.Hidden = True
Else: Columns("M:O").Select
Selection.EntireColumn.Hidden = False
For Each BrokerCell In Rng
If BrokerCell <> "" And Range("$S$5").Value <> "" Then
Wks.Range("$B$5").Value = BrokerCell.Text
Wks.PrintOut
End If
Next BrokerCell
End If
End Sub
Your For Each loop is contained within the Else portion of the If Range("$A$5").Value = "Company 2" Then statement. It will only execute when that If statement evaluates to false.
If you need your For Each loop to execute in all instances, then move it after the End If. If you need it to execute only when the If statement evaluates to True, then move it before the Else.
I believe this is what oyu are looking to accomplish, see below.
Sub PrintAll()
Dim BrokerCell As Range
Dim TotalCell As Range
Dim Rng As Range
Dim Wks As Worksheet
Dim sCellValue As String
Set Wks = Worksheets("PRINT PAGE")
sCellValue = Replace(Range("$A$5").Value, " ", "")
If sCellValue = "Company1" Then
Set Rng = ThisWorkbook.Names(sCellValue ).RefersToRange
ElseIf sCellValue = "Company2" Then
Set Rng = ThisWorkbook.Names(sCellValue ).RefersToRange
Else
Set Rng = ThisWorkbook.Names("Company3").RefersToRange
End If
Columns("M:O").Select
If sCellValue = "Company2" Then
Selection.EntireColumn.Hidden = True
Else
Selection.EntireColumn.Hidden = False
End If
For Each BrokerCell In Rng
If BrokerCell <> "" And Range("$S$5").Value <> "" Then
Wks.Range("$B$5").Value = BrokerCell.Text
Wks.PrintOut
End If
Next BrokerCell
End Sub
Related
I am creating a macro that is supposed to separate and add new worksheets based off one worksheet with all the data in it.
It won't run and I'm not sure why.
My code keeps hitting a Run Time Error '9': Script out of range. I'm not sure if it has something to do with the first sub or the second sub.
The error occurs on line 16:
Set wsMain = wbMain.Sheets("MAIN")
First sub:
Option Explicit
Sub main()
Dim wbMain As Workbook
Dim wsMain As Worksheet
Dim rngMain As Range
Dim RngCategoryOne As Range
Dim RngCategoryTwo As Range
Dim RngCategoryThree As Range
Dim RngCategoryFour As Range
Dim RngCategoryFive As Range
Dim RngCategorySix As Range
Dim rng As Range
Dim SheetNames As Variant
Dim str As Variant
Set wbMain = ActiveWorkbook
Set wsMain = wbMain.Sheets("MAIN")
Set rngMain = wsMain.Range("F2:F3000")
For Each rng In rngMain
Select Case rng
Case "HO NMX_AMO", "HO NMX_EUR", "WTI NMX", "DIESEL OHR EIA_AMO"
If RngCategoryOne Is Nothing Then
Set RngCategoryOne = rng
Else
Set RngCategoryOne = Union(rng, RngCategoryOne)
End If
Case "WTI NMX_AMO"
If RngCategoryTwo Is Nothing Then
Set RngCategoryTwo = rng
Else
Set RngCategoryTwo = Union(rng, RngCategoryTwo)
End If
Case "NG HH NMX"
If RngCategoryThree Is Nothing Then
Set RngCategoryThree = rng
Else
Set RngCategoryThree = Union(rng, RngCategoryThree)
End If
Case "RBOB NMX_EUR", "RBOB NMX_AMO"
If RngCategoryFour Is Nothing Then
Set RngCategoryFour = rng
Else
Set RngCategoryFour = Union(rng, RngCategoryFour)
End If
Case "GO ICE_AMO"
If RngCategoryFive Is Nothing Then
Set RngCategoryFive = rng
Else
Set RngCategoryFive = Union(rng, RngCategoryFive)
End If
Case "C3 CONW INW OPIS_APO, C3 MBEL TET OPIS_APO"
If RngCategorySix Is Nothing Then
Set RngCategorySix = rng
Else
Set RngCategorySix = Union(rng, RngCategorySix)
SheetNames = Array("AT, LB, LC, AS", "AO", "LN", "RF, RA", "ULA2", "8K, BO")
For Each str In SheetNames
Call AddNewWorksheet(wbMain, str)
Next str
wbMain.Sheets("AT, LB, LC, AS").Range("A1:A" & RngCategoryOne.Count) = RngCategoryOne.Value
wbMain.Sheets("AO").Range("A1:A" & RngCategoryTwo.Count) = RngCategoryTwo.Value
wbMain.Sheets("LN").Range("A1:A" & RngCategoryThree.Count) = RngCategoryThree.Value
wbMain.Sheets("RF, RA").Range("A1:A" & RngCategoryFour.Count) = RngCategoryFour.Value
wbMain.Sheets("ULA2").Range("A1:A" & RngCategoryFive.Count) = RngCategoryFive.Value
wbMain.Sheets("8K, BO").Range("A1:A" & RngCategorySix.Count) = RngCategorySix.Value
wsMain.Activate
wsMain.Range("A1").Select
End If
End Select
Next
End Sub
Second Sub:
Sub AddNewWorksheet(ByRef wb As Workbook, ByVal wsName As Variant)
With wb.Sheets
.Add(after:=wb.Sheets(.Count)).Name = wsName
End With
End Sub
I am very new to macro programming and currently creating a macro that splits a table into new worksheets dependent on a unique variable, then copies and pastes each worksheet into a single word document split by page breaks.
What I cannot work out how to do, is create a macro that gives each table on each page a title based on the value of a cell.
Option Explicit
Sub Run_All()
Call Organise_Table
Call Rename_Column
Call Isblank
Call Split_Table
Call SumColumn
Call ExceltoWord
Call Report_Title
End Sub
Sub Organise_Table()
Columns(1).EntireColumn.Delete
Columns(1).EntireColumn.Delete
Columns(2).EntireColumn.Delete
Columns(3).EntireColumn.Delete
Columns(3).EntireColumn.Delete
End Sub
Sub Rename_Column()
Range("A1") = "Contribution Type"
Range("B1") = "RefNo"
Range("C1") = "Title"
Range("D1") = "Initals"
Range("E1") = "Surname"
Range("F1") = "Balance Brought Forward"
Range("G1") = "Annual Interest Added"
Range("H1") = "Contributions Added"
Range("I1") = "Total Fund Value"
End Sub
Sub Isblank()
Application.ScreenUpdating = False
On Error Resume Next
With Range("F1:I14")
.SpecialCells(xlCellTypeBlanks).Formula = "0"
.Value = .Value
End With
Err.Clear
Application.ScreenUpdating = True
End Sub
Sub Split_Table()
Dim lr As Long
Dim Ws As Worksheet
Dim vcol As Integer
Dim i As Integer
Dim iCol As Long
Dim myarr As Variant
Dim Title As String
Dim titlerow As Integer
vcol = 2
Set Ws = Sheets("Sheet1")
Title = "A1:I14"
Application.ScreenUpdating = False
lr = Ws.Cells(Ws.Rows.Count, vcol).End(xlUp).Row
titlerow = Ws.Range(Title).Cells(1).Row
iCol = Ws.Columns.Count
Ws.Cells(1, iCol) = "Unique"
For i = 2 To lr
On Error Resume Next
If Ws.Cells(i, vcol) <> "" And Application.WorksheetFunction.Match(Ws.Cells(i, vcol), Ws.Columns(iCol), 0) = 0 Then
Ws.Cells(Ws.Rows.Count, iCol).End(xlUp).Offset(1) = Ws.Cells(i, vcol)
End If
Next i
myarr = Application.WorksheetFunction.Transpose(Ws.Columns(iCol).SpecialCells(xlCellTypeConstants))
Ws.Columns(iCol).Clear
For i = 2 To UBound(myarr)
Ws.Range(Title).AutoFilter field:=vcol, Criteria1:=myarr(i) & ""
If Not Evaluate("=ISREF('" & myarr(i) & "'!A1)") Then
Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = myarr(i) & ""
Else
Sheets(myarr(i) & "").Move after:=Worksheets(Worksheets.Count)
End If
Ws.Range("A" & titlerow & ":A" & lr).EntireRow.Copy Sheets(myarr(i) & "").Range("A1")
Sheets(myarr(i) & "").Columns.AutoFit
Next i
Ws.AutoFilterMode = False
Ws.Activate
End Sub
Sub SumColumn()
Dim LastRow As Long
Dim iRow As Long
Dim iCol As Integer
Dim nSheets As Integer
For nSheets = 1 To 3
With Worksheets(nSheets)
LastRow = 0
For iCol = 6 To 9
iRow = .Cells(65536, iCol).End(xlUp).Row
If iRow > LastRow Then LastRow = iRow
Next iCol
For iCol = 6 To 9
.Cells(LastRow + 1, iCol) = Application.WorksheetFunction.Sum(Range(.Cells(1, iCol), .Cells(LastRow, iCol)))
Next iCol
iCol = 1
.Cells(LastRow + 1, iCol).Value = ("Total")
End With
Next nSheets
End Sub
Sub ExceltoWord()
Dim Ws As Worksheet
Dim Wkbk1 As Workbook
Dim strdocname As String
Dim wdapp As Object
Dim wddoc As Object
Dim orng As Object
Dim wdAutoFitwindow As String
Set Wkbk1 = ActiveWorkbook
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.EnableEvents = False
strdocname = "\\VDC.COM\User\HomeDrives\GFSNRE\Desktop\Test19.Doc" 'Change this to whatever directory the report will be in
'file name & folder path
On Error Resume Next
'error number 429
Set wdapp = GetObject(, "Word.Application")
If Err.Number = 429 Then
Err.Clear
'create new instance of word application
Set wdapp = CreateObject("Word.Application")
End If
wdapp.Visible = True
'define paths to file
If Dir(strdocname) = "" Then
'MsgBox "The file" & strdocname & vbCrLf & "was not found " & vbCrLf & "C:\Path\Name.doc", _
' vbExclamation, "The document does not exist "
'Exit Sub
Set wddoc = wdapp.Documents.Add
Else
Set wddoc = wdapp.Documents.Open(strdocname)
End If
For Each Ws In Wkbk1.Worksheets
Ws.Range("A1:I14").Copy
Set orng = wddoc.Range
orng.collapse 0
orng.Paste
orng.End = wddoc.Range.End
orng.collapse 0
orng.insertbreak Type:=7
Range("A1:I14").Borders.LineStyle = xlContinuous
wddoc.AutofitBehavior wdAutoFitwindow
Next Ws
lbl_Exit:
Set orng = Nothing
Set wddoc = Nothing
Set wdapp = Nothing
Set Wkbk1 = Nothing
Set Ws = Nothing
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.EnableEvents = True
Exit Sub
End Sub
Sub Report_Title()
Dim Ws As Worksheet
Dim MyText As String
Dim MyRange As Object
Set MyRange = ActiveWorkbook.Range
MyText = Ws.Range("E3").Value
' Selection Example:
Selection.InsertBefore (MyText)
' Range Example: Inserts text at the beginning
' of the active document.
MyRange.InsertBefore (MyText)
End Sub
There is one error here :
Dim Ws As Worksheet
Dim MyText As String
Dim MyRange As Object
Set MyRange = ActiveWorkbook.Range
MyText = Ws.Range("E3").Value '<==== WS is not properly defined yet
You are using Ws. to say in which worksheet you are working in, which is a good thing. But, as it is a procedure-level variable, it is not pointing anywhere useful. You probably need something like :
Set MyRange = ActiveWorkbook.Range
Set Ws = ActiveWorkbook.Sheets("Sheet1") 'assuming you want to read "E3" on the sheet "Sheet1" of the active workbook, that's the line to add
MyText = Ws.Range("E3").Value '<==== WS is now properly defined
If you go to debugging mode, you should have nothing in "MyText" in your version, and something in mine. The content of E3 in the sheet Sheet1.
Two things:
You should not turn off error handling for the entire code. If
things aren't working VBA can't tell you why or where the problem
is. While it's standar practise to use On Error Resume Next when
using GetObject/CreateObject it's also standard practise to turn
error handling back on AFTER the If...End If. You need to add the
line: On Error GoTo 0 where you have no error handler code.
Based on your sample code, write in the Title before pasting the table.
So something like this:
For Each Ws In Wkbk1.Worksheets
Ws.Range("A1:I14").Copy
Set orng = wddoc.Range
orng.collapse 0
orng.Text = Ws.Range([cell reference with title]) & vbCr
orng.collapse 0
orng.Paste
orng.End = wddoc.Range.End
orng.collapse 0
orng.insertbreak Type:=7
Range("A1:I14").Borders.LineStyle = xlContinuous
wddoc.AutofitBehavior wdAutoFitwindow
Next Ws
This is a subroutine of a larger program (I can copy and paste the whole thing if needed). I'm getting an unknown runtime error, and I can't for the life of me figure out why. I've spent a couple hours getting frustrated, and decided to come to you guys for help!
Quick Edit: I'm trying to find a specific column header, and then select that entire column (minus the header) as the range.
Sub YearSmash(MyString)
With objSheetSrc
Set FoundCell = .Range("A1:BZ1").Find(MyString, , , 1)
If FoundCell Is Nothing Then
Exit Sub
End If
MsgBox(FoundCell)
Set rng1 = .Range(FoundCell.Offset(1), FoundCell.Offset(1).End(xlDown))
MsgBox(rng1)
End With
End Sub
Error is occuring on the following line:
Set rng1 = .Range(FoundCell.Offset(1), FoundCell.Offset(1).End(xlDown))
Any ideas? Also, there are no invalid values, errors, or NULL values in the data I am trying to pull.
Thanks,
Andrew
Editted to show code in its entirety:
Const xlFilterCopy = 2
strPathSrc = "C:\test" ' Source files folder
strMaskSrc = "*.xlsx" ' Source files filter mask
dtmDate = Date
strMonth = Month(Date)
strDay = Day(Date)
strYear = Right(Year(Date), 2)
strFileName = "C:\test\Results\" & strMonth & "-" & StrDay & "-" & strYear & " Results.xlsx"
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = False
Set objWorkbook = objExcel.Workbooks.Add()
objWorkbook.SaveAs(strFileName)
objExcel.Quit
'strPathDst = "C:\test\Results\Results.xlsx" ' Destination file
strPathDst = strFileName
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = False
Set objWorkBookDst = objExcel.Workbooks.Open(strPathDst)
Set objShellApp = CreateObject("Shell.Application")
Set objFolder = objShellApp.NameSpace(strPathSrc)
Set objItems = objFolder.Items()
objItems.Filter 64 + 128, strMaskSrc
objExcel.DisplayAlerts = False
x = 1
y = 1
MsgBox("Working")
For Each objItem In objItems
Set objWorkBookSrc = objExcel.Workbooks.Open(objItem.Path)
Set objSheetSrc = objWorkBookSrc.Sheets(1)
Set objSheetDst = objWorkBookDst.Sheets(1)
For Each Cell In objSheetSrc.Range("A1:Z15")
If Cell.MergeCells = True Then
Set objRange = Cell.EntireRow
objRange.Delete
End If
Next
'Set FoundCell = objSheetSrc.Range("A1:BZ1").Find("Device", , , 1)
'For Each Cell In objSheetSrc.Range(FoundCell.Offset(1,0), objSheetSrc.Cells(objSheetSrc.Rows.Count, FoundCell.Column).End(-4162)).Cells
'If Cell.Value <> "*MSP430*" Then
' Cell.EntireRow.Delete
'End If
'Next
Set objSheetDst = objWorkBookDst.Sheets(1)
Call FindCell("Sales Region")
Call FindCell("Sales Area")
Call FindCell("TSR Role")
Call FindCell("My Account")
Call FindCell("Account Class")
Call FindCell("Project Name")
Call FindCell("Device")
Call FindCell("AUP")
Call FindCell("Qty Per Board")
Call FindCell("Device Status")
Call FindCell("Project Status")
Call FindCell("Project Kickoff")
Call FindCell("Market")
Call FindCell("SBE")
Call FindCell("SBE-1")
Call FindCell("SBE-2")
Call FindCell("2013 Q1")
Call FindCell("2013 Q2")
Call FindCell("2013 Q3")
Call FindCell("2013 Q4")
Call FindCell("2014 Q1")
Call FindCell("2014 Q2")
Call FindCell("2014 Q3")
Call FindCell("2014 Q4")
Call FindCell("2015 Q1")
Call FindCell("2015 Q2")
Call FindCell("2015 Q3")
Call FindCell("2015 Q4")
Call FindCell("2016")
Call YearSmash("2016 Q1")
Call FindCell("2016 Q1")
Call FindCell("2017")
Call FindCell("2018")
objWorkBookSrc.Close
Next
objExcel.Visible = True
Sub FindCell(MyString)
Do While objSheetDst.Cells(x, y).Value <> ""
y = y + 1
Loop
If MyString = "Sales Region" And y > 2 Then
y = 1
Do While objSheetDst.Cells(x, y).Value <> ""
x = x + 1
Loop
End If
Set FoundCell = objSheetSrc.Range("A1:BZ1").Find(MyString, , , 1)
If FoundCell Is Nothing Then
Exit Sub
End If
Set objRangeSrc = FoundCell.EntireColumn
objRangeSrc.AdvancedFilter xlFilterCopy, , objSheetDst.Cells(x, y), False
End Sub
Sub YearSmash(MyString)
With objSheetSrc
Set FoundCell = .Range("A1:BZ1").Find(MyString, , , 1)
If FoundCell Is Nothing Then Exit Sub
Set lRow = .Cells(.Rows.Count, FoundCell.Column).End(xlUp).Row
Set rng1 = .Range(.Cells(FoundCell.Row + 1, FoundCell.Column), .Cells(lRow, FoundCell.Column))
MsgBox rng1.Address
End With
End Sub
Is this what you are trying?
Sub YearSmash(MyString)
Dim objSheetSrc As Worksheet
Dim lRow As Long
Dim FoundCell As Range, rng1 As Range
Dim MyString As String
'~~> Change as applicable
Set objSheetSrc = ThisWorkbook.Sheets("Sheet1")
With objSheetSrc
Set FoundCell = .Range("A1:BZ1").Find(MyString, , , 1)
If FoundCell Is Nothing Then Exit Sub
'~~> Find the last row in that column
lRow = .Cells(.Rows.Count, FoundCell.Column).End(xlUp).Row
'~~> Construct your range from one cell offset
Set rng1 = .Range(.Cells(FoundCell.Row + 1, FoundCell.Column), _
.Cells(lRow, FoundCell.Column))
MsgBox rng1.Address
End With
End Sub
FOLLOWUP FROM COMMENTS
I tested it in vbscript and it works perfectly
Dim oXLApp, olXLWb, objSheetSrc
Dim MyString, lRow, FoundCell, rng1
Set oXLApp = CreateObject("Excel.Application")
oXLApp.Visible = True
'~~> Sample File
Set olXLWb = oXLApp.Workbooks.Open("C:\Sample.xlsx")
'~~> Change as applicable
Set objSheetSrc = olXLWb.Sheets("Sheet1")
'~~> Sample String
MyString = "Sid"
With objSheetSrc
Set FoundCell = .Range("A1:BZ1").Find(MyString, , , 1)
If Not FoundCell Is Nothing Then
'~~> Find the last row in that column
lRow = .Cells(.Rows.Count, FoundCell.Column).End(-4162).Row
'~~> Construct your range from one cell offset
Set rng1 = .Range(.Cells(FoundCell.Row + 1, FoundCell.Column), _
.Cells(lRow, FoundCell.Column))
MsgBox rng1.Address
End If
End With
I need to create an IF AND THEN statement in my vba. I've tried this code below and although I get no errors it doesn't work (ie: nothing happens when I run the macro):
Sub PrintAll()
Dim BrokerCell As Range
Dim Rng As Range
Dim Wks As Worksheet
Set Wks = Worksheets("PRINT PAGE")
If Range("$A$5").Value = "Company 1" Then
Set Rng = ThisWorkbook.Names("Company1").RefersToRange
ElseIf Range("$A$5").Value = "Company2" Then
Set Rng = ThisWorkbook.Names("Company2").RefersToRange
Else: Set Rng = ThisWorkbook.Names("Company3").RefersToRange
End If
For Each BrokerCell In Rng
If BrokerCell <> "" AND "$Q$5" > "0" Then
Wks.Range("$B$5").Value = BrokerCell.Text
Wks.PrintOut
End If
Next BrokerCell
End Sub
The macro works without the
AND "$Q$5" > "0"
so clearly I'm doing something wrong here.
You probably mean:
If BrokerCell <> "" And Range("$Q$5").Value > 0
You're comparing the literal string "$Q$5" to the literal string "0".
I'm a newbie at vba so please excuse my ignorance. I created a macro that will run through a dropdown list and print for each name in the dropdown - and it works:
Sub PrintAll()
Dim Cell As Range
Dim Rng As Range
Dim Wks As Worksheet
Set Wks = Worksheets("PRINT PAGE")
Set Rng = ThisWorkbook.Names("Brokers").RefersToRange
For Each Cell In Rng
If Cell <> "" Then
Wks.Range("$B$5").Value = Cell.Text
Wks.PrintOut
End If
Next Cell
End Sub
However, the workbook has multiple worksheets to read from and therefore I need the vba to read from multiple ranges so I tried this
Sub PrintAll()
Dim Cell As Range
Dim Cell2 As Range
Dim Rng As Range
Dim Wks As Worksheet
Set Wks = Worksheets("PRINT PAGE")
If "$A$5" = "Company1" Then Rng = ThisWorkbook.Names("1Brokers").RefersToRange
ElseIf "$A$5" = "Company2" Then Rng = ThisWorkbook.Names("2Brokers").RefersToRange
Else: Set Rng = ThisWorkbook.Names("3Brokers").RefersToRange
End If
For Each Cell In Rng
If Cell <> "" Then
Wks.Range("$B$5").Value = Cell.Text
Wks.PrintOut
End If
Next Cell
End Sub
The problem is I keep getting "Compile error Else without If" on the If statement. Is there something wrong with how I'm setting up the If statement or with how I'm using it in the code?
This block compiles for me. Please test it. I have always start set in the after then in if.
Sub PrintAll()
Dim Cell As Range
Dim Cell2 As Range
Dim Rng As Range
Dim Wks As Worksheet
'Set Wks = Worksheets("PRINT PAGE")
If "$A$5" = "Company1" Then
Rng = ThisWorkbook.Names("1Brokers").RefersToRange
ElseIf "$A$5" = "Company2" Then
Rng = ThisWorkbook.Names("2Brokers").RefersToRange
Else
Set Rng = ThisWorkbook.Names("3Brokers").RefersToRange
End If
For Each Cell In Rng
If Cell <> "" Then
Wks.Range("$B$5").Value = Cell.Text
Wks.PrintOut
End If
Next Cell
End Sub
Use
If Range("$A$5").Value = "Company1"..
Similarly for "$A$5".
"$A$5" is just a string and you are comparing a string to a string. What you want is a range object
EDIT
Regarding the Error that you are getting, you have to use Then
The syntax is (Hiten004 post made me realize it)
If <Cond> Then
ElseIF <Cond> Then
End If
Rather than:
If "$A$5" = "Company1" Then Rng = ThisWorkbook.Names("1Brokers").RefersToRange
use:
If "$A$5" = "Company1" Then Set Rng = ThisWorkbook.Names("1Brokers").RefersToRange
There may be other problems in your code.