This is what I am working on. I have a workbook that is exporting data, running data through a couple of other macros to sort and format it before inserting the data into a formatted worksheet that will have a "Print to PDF" button. What I am running into is that the print area on this ends up printing hundreds of pages.
My suspicion is that this is happening because I use an excel formula that is modifying the data in every column. The answer MAY be to write this out as VBA code instead of nesting the formulas in the columns. But I think it is counting the cells down through these rows because it has a formula even though the cell itself is blank. Does that make sense? Or can you see any other problems??
Option Explicit
Const EXPORTS As String = "P:\Public\Generated Letters\LTXN Export Spreadsheets\"
Sub Create_PDF()
Dim ws As Worksheet
Dim AccountNumber As String, dt As String, FullName As String, fName As String, sep As String
Dim myrange As String
Set ws = ActiveSheet
AccountNumber = Right(ws.Range("A3").Value, 3) 'not just `A3`
'sets the string end for the print area
myrange = Cells(Rows.Count, 6).End(xlUp).Address
With ActiveSheet.PageSetup
.PrintArea = "A1:" & myrange
.Orientation = xlLandscape
.Zoom = False
.FitToPagesTall = False
.FitToPagesWide = 1
End With
dt = Format(Now, "mm.dd.yyyy hh mm")
fName = EXPORTS & "AccountEnding" & AccountNumber & " - Created On - "
If Len(Dir(fName & ".pdf")) > 0 Then sep = " - "
fName = fName & sep & dt & ".pdf"
ws.ExportAsFixedFormat Type:=xlTypePDF, Filename:=fName, _
Quality:=xlQualityStandard, IncludeDocProperties:=False, _
IgnorePrintAreas:=False, OpenAfterPublish:=True
Call Shell("explorer.exe" & " " & "P:\Public\Generated Letters\LTXN Export Spreadsheets\", vbNormalFocus)
End Sub
So I found an update as I have been milling around on this, it seems like a copy and insert function is causing the issue here. I have this code run before the print to pdf code:
Sub Data_Filter()
If CountRows = ThisWorkbook.Worksheets("LTXN Data").Range("A:A").Cells.SpecialCells(xlCellTypeConstants).Count > 5000 Then
MsgBox ("Due to the number of transactions please reach out to David Wallenburg for assistance.")
Exit Sub
End If
Application.DisplayAlerts = False
Sheets("LTXN Data").Select
Range("A2:I2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets("LTXN Formatting").Select
Range("A1:I1").PasteSpecial
Application.CutCopyMode = False
Sheets("LTXN Formatting").Select
Range("M1:R1").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Worksheets("LTXN Formatting Sort").Visible = True
Sheets("LTXN Formatting Sort").Select
Range("a1:f1").PasteSpecial xlPasteValues
Application.CutCopyMode = False
Columns("A:F").Sort key1:=Range("E1"), Order1:=xlDescending
Range("A1:F1").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Worksheets("LTXN Report").Visible = True
Sheets("LTXN Report").Select
Range("A6:F6").Select
Selection.Insert xlShiftDown
Application.CutCopyMode = False
Dim myrange As String
myrange = Cells(Rows.Count, 6).End(xlUp).Address
Sheets("LTXN Report").Range(Selection, ("a1:" & myrange)).Select
ActiveSheet.Range("A1:" & myrange).BorderAround ColorIndex:=1, Weight:=xlThick
Application.DisplayAlerts = True
Sheets("LTXN Report").Activate
End Sub
I think the problem is that when it goes to the LTXN Formatting Sort page it is selecting much more than the columns with DATA. IS there an easy fix i am missing?
Two ways to go about this then. The first one is to use array formulas, specifically Filter(Range,criteria) and depending on how complicated the data is, you might want to have a separate row to determine what data to include. In my example I'm using:
=COUNTIF(E2:G2,"-/-")<>3
Then I have the "Output Report" section, which can be moved to separate page if need be, by using the formula:
=FILTER(E2:G31,I2:I31)
(to note, I'm using "-/-" instead of "" just to help show the blank spaces.)
You Can now confidently use range("somerange").end(xlup).row to find last row
OR -
If you have no blank rows, you can use
Sheet4.Range("E:E").Find(what:="", LookIn:=xlValues).Row -1
and that will give you the first row without data.
However, if you have some rows that may have nothing in them, you might want to pull the data into an array and step backwards through it to find last row:
Option Explicit
Sub Set_Print_Area()
Dim I
Dim iLow As Long
Dim iHigh As Long
Dim RG
iHigh = Sheet4.Range("E" & Rows.Count).End(xlUp).Row
Set RG = Sheet4.Range("E1:E" & iHigh)
For I = iHigh To 1 Step -1
If RG(I) <> "" Then
Debug.Print I
ActiveSheet.PageSetup.PrintArea = "E1:G" & I
Exit For
End If
Next I
End Sub
Hopefully one of these methods helps.
Related
Goal of this code:
Apply filter at Range A2 in Final Salary Sheet based upon value of Menu Sheet Range "E6"
Copy A1:M1 data as header
and then Copy filter data to A2 range in new sheet, rename the new sheet and save the new sheet to specific folder with specified name.
Error I am facing:
A1:m1 range is perfectly getting copy pasted. but filter data is not getting copy pasted. Also please note A1 range in Final Salary Sheet is a Logo/Image.
Sub selfcopy()
Dim exclfile As String
Dim fdObj As Object
Dim year As String
Dim month As String
year = Sheets("Menu").Range("e4").Text
month = Sheets("Menu").Range("e6").Text
Application.ScreenUpdating = False
Set fdObj = CreateObject("Scripting.FileSystemObject")
If fdObj.FolderExists("\\Account\e\SATYA\BANK\1-SALARY SHEET\1-TRANSFER\" & year & "\" & month) Then
On Error Resume Next
Else
fdObj.CreateFolder ("\\Account\e\SATYA\BANK\1-SALARY SHEET\1-TRANSFER\" & year & "\" & month)
End If
Application.ScreenUpdating = True
exclfile = "Salary File" & "-" & Sheets("Menu").Range("E6").Text
Set Newbook = Workbooks.Add
ThisWorkbook.Worksheets("Final Salary").Select
Range("A1:M1").copy
Newbook.Worksheets("UBI Bank").Range("A1").Activate
Activesheet.paste
Newbook.Worksheets("Sheet1").Name = "Salaryoutput"
Newbook.Worksheets("Salaryoutput").Select
ThisWorkbook.Worksheets("Final Salary").Select
Range("A2").Select
ActiveSheet.Range("$A$2:$W$99999").AutoFilter Field:=1, Criteria1:=Array(1, Sheets("Menu").Range("E6").Text)
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.SpecialCells(xlCellTypeVisible).Select
Selection.Copy
Newbook.Worksheets("salaryoutput").Range("A2").Activate
ActiveSheet.Paste
Application.CutCopyMode = False
Newbook.SaveAs Filename:="\\Account\e\SATYA\BANK\1-SALARY SHEET\1-TRANSFER\" & year & "\" & month & "\" & exclfile
ThisWorkbook.Worksheets("Menu").Select
MsgBox ("Excel has been saved to Bank Folder")
End Sub
I am quite new with Excel VBA.
This line Newbook.Worksheets("UBI Bank").Range("A1").Activate fails because a new book will not have a sheet with that name.
Option Explicit
Sub selfcopy()
Const FOLDER = "\\Account\e\SATYA\BANK\1-SALARY SHEET\1-TRANSFER\"
Dim wbNew As Workbook
Dim fdObj As Object, exclfile As String, exclfolder As String
Dim year As Long, month As Long, lastrow As Long
With Sheets("Menu")
year = .Range("E4").Value2
month = .Range("E6").Value2
exclfile = "Salary File" & "-" & Format(month, "00")
exclfolder = FOLDER & year & "\" & month
End With
Set fdObj = CreateObject("Scripting.FileSystemObject")
If Not fdObj.FolderExists(exclfolder) Then
fdObj.CreateFolder exclfolder
MsgBox exclfolder & " created"
End If
Set wbNew = Workbooks.Add(1)
With wbNew
.Sheets(1).Name = "Salaryoutput"
End With
With Sheets("Final Salary")
lastrow = .Cells(.Rows.Count, 1).End(xlUp).Row
.Range("A1:M1").Copy wbNew.Sheets(1).Range("A1")
With .Range("A2:W" & lastrow)
.AutoFilter Field:=1, Criteria1:=month
.SpecialCells(xlCellTypeVisible).Copy wbNew.Sheets(1).Range("A2")
End With
End With
wbNew.SaveAs Filename:=exclfolder & "\" & exclfile
wbNew.Close savechanges:=False
Sheets("Menu").Activate
MsgBox "Excel has been saved to " & exclfile, vbInformation, exclfolder
End Sub
Below is the code I am trying to work on. I am new to Excel VBA.
Sub Test1()
Dim x As Integer
Application.ScreenUpdating = False
' Set numrows = number of rows of data.
NumRows = Range("A2", Range("A2").End(xlDown)).Rows.Count
For x = 1 To NumRows
ActiveSheet.OLEObjects.Add(Filename:= _
"Filelocation\filename.extension" _
, Link:=False, DisplayAsIcon:=True, IconFileName:="C:\Windows\Installer\{90160000-000F-0000-1000-0000000FF1CE}\wordicon.exe", _
IconIndex:=0, IconLabel:= _
"Filelocation\filename.extension" _
).Select
ActiveCell.Offset(1, 0).Select
Next
Application.ScreenUpdating = True
End Sub
Here I want to attach the next file in the folder.
As of now with this code, I can attach the same file multiple times.
My requirement is to attach different files in different cells as I move down.
I hope the question was clear :)
I have created a sheet named Control which has the location of the files to be attached with a button with the below macro assigned to it.
Sub fileInsertionForRetest()
On Error GoTo er
Dim x As Integer
Dim NumRows As Long
Worksheets("Retest").Activate
Application.ScreenUpdating = False
Range("G2").Select
NumRows = Range("A2", Range("A2").End(xlDown)).Rows.Count
For x = 1 To NumRows
Range("B" & x + 1&).EntireRow.RowHeight = 60
ActiveSheet.OLEObjects.Add(Filename:= _
ThisWorkbook.Sheets("Control").Range("B2").Value & Range("A" & x + 1&).Value & ".docx", Link:=False, DisplayAsIcon:=True, _
IconFileName:="C:\Windows\Installer\{90160000-000F-0000-1000-0000000FF1CE}\wordicon.exe", _
IconIndex:=0, IconLabel:=Range("A" & x + 1&).Value).Select
ActiveCell.Offset(1, 0).Select
Next
Application.ScreenUpdating = True
Done:
MsgBox "All file were attached successfully"
Exit Sub
er:
MsgBox "The following error occurred: " & err.Description
End Sub
I am writing some code for splitting up an excel sheet by a specific column into separate workbooks. My code works but is really slow (It should create 28 separate files and takes around 10 min per file). What can I do to make it perform better? Is there a way to save some calculation time?
Sub Split()
Dim wswb As String
Dim wssh As String
Dim path As String
Worksheets("Sheet1").Activate
wswb = ActiveWorkbook.Name
wssh = ActiveSheet.Name
path = Worksheets("Start").Range("H6").Value
Columns("H").Copy
Worksheets("Settings").Activate
Range("A1").PasteSpecial
Columns("A").RemoveDuplicates Columns:=1, Header:=xlYes
vCounter = Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To vCounter
vFilter = Sheets("Settings").Cells(i, 1)
Sheets(wssh).Activate
ActiveWorkbook.Worksheets("Sheet1").AutoFilterMode = False
ActiveSheet.ListObjects("Table1").Range.AutoFilter Field:=8, Criteria1:=vFilter
Cells.Copy
Workbooks.Add
Range("A1").PasteSpecial
Worksheets("Sheet1").Name = "OTD"
Sheets.Add After:=ActiveSheet
ActiveCell.FormulaR1C1 = ""
Sheets("Sheet2").Select
Sheets("Sheet2").Name = "PPM"
Sheets("OTD").Select
If vFilter <> "" Then
ActiveWorkbook.SaveAs path & "OTD_PPM_Report_" & Format(DateSerial(Year(Date), month(Date) - 1, 1), "mmm_yyyy") & "_" & Range("I2").Value & ".xlsx"
End If
ActiveWorkbook.Close
Workbooks(wswb).Activate
Next i
ActiveSheet.ListObjects("Table1").Range.AutoFilter Field:=8
End Sub
In general I prefer to use:
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
to increase performance every time dealing with excel files. I also use:
Application.Visible = False
which I also believe increase speed.
These are just general remarks.
Ps. Also try to avoid Activate / Select (this may help How to avoid using Select in Excel VBA)
I have a macro code to open several excel sheets one after the other (I only show 3 here):
Sub Macro1()
Workbooks.Open Filename:=Range("F19").Value, UpdateLinks:=0
ActiveWindow.Visible = True
Windows("Data Quality Checks - ITS v2.8.xlsm").Activate
Workbooks.Open Filename:=Range("F21").Value, UpdateLinks:=0
ActiveWindow.Visible = True
Windows("Data Quality Checks - ITS v2.8.xlsm").Activate
Workbooks.Open Filename:=Range("F23").Value, UpdateLinks:=0
ActiveWindow.Visible = True
Windows("Data Quality Checks - ITS v2.8.xlsm").Activate
End Sub
The 'Range' shows the cell with the specific file path.
Currently, if the macro does not find one of the files, it produces an error and the process is forced to stop. Is it possible to include an additional line code that if the file is not found in the specified path, then the process continues and does not stop (no debugging)?
This may helps:
Option Explicit
Sub Macro1()
Dim LastRow As Long, i As Long
Dim PathName As String, MissingFiles As String
With ThisWorkbook.Worksheets("Sheet1")
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
For i = 19 To LastRow Step 2 '<- Start from 19 like the example and stop lastrow column A sheet 1. Loop every two.
PathName = .Range("A" & i).Value
If Len(Dir(PathName)) = 0 Then '<- Make sure you add the extension of the file.
If MissingFiles = "" Then
MissingFiles = PathName
Else
MissingFiles = MissingFiles & vbNewLine & PathName
End If
Else
Workbooks.Open Filename:=PathName, UpdateLinks:=0
ActiveWindow.Visible = True
' Windows("Data Quality Checks - ITS v2.8.xlsm").Activate
End If
Next i
MsgBox "Missing Files are: " & vbNewLine & MissingFiles
End With
End Sub
Sheet Structure:
Message Box :
I have "Filling form" worksheet where user is filling information and then I have "Print version" worksheet that is actually printing. I am making "CV tool" so user is filling his personal information and then my current VBA is saving end file from "Print version" to xls. and .pdf to the same folder with certain name both files where my "CV tool" is. Some people have experience of 10 years in 10 different work places and others have been only in 2 different companies previously. So before saving to .pdf and .xls my VBA hides rows that are empty to make end result look good.
The problem is that estetically it is not so good looking because some heading of work positions are at the end of the page and work description is continuing on the next page. Is there any way to make some kind of VBA to look for each page in "PrintArea" and if certain block is not fitting to this page VBA will insert "Page Break" before it to move it to the next page?
My current macro below (Sub doitallplease() is main command):
Sub Color()
Dim myRange As Range
Dim cell As Range
Set myRange = ThisWorkbook.Sheets("Print version").Range("Print_Area")
For Each cell In myRange
myRange.Interior.ColorIndex = 0
If cell.HasFormula = True And cell.value = "" And cell.EntireRow.Hidden = False Then Rows(cell.Row).EntireRow.Hidden = True
Next
End Sub
Sub MagicButton()
Dim iFileName$, iRow&, iCol&, iCell As Range, iArr
iFileName = ThisWorkbook.Path & "\CV_" & Sheets("Filling form").Range("F7") & "_" & Sheets("Filling form").Range("F9") & ".xls"
iArr = Array(1, 3, 4): iCol = UBound(iArr) + 1
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.Calculation = xlManual
ThisWorkbook.Sheets("Print version").Copy
With ActiveWorkbook.ActiveSheet
.Buttons.Delete '.Shapes("Button 1").Delete
.UsedRange.value = .UsedRange.value
.SaveAs iFileName, xlExcel8: .Parent.Close
End With
Application.Calculation = xlAutomatic
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Sub exportpdfthisfile()
ActiveWorkbook.Sheets("Print version").Select
ActiveSheet.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=ThisWorkbook.Path & "\CV_" & Sheets("Filling form").Range("F7") & "_" & Sheets("Filling form").Range("F9") & ".pdf", _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
End Sub
Sub doitallplease()
Application.ScreenUpdating = False
ActiveWorkbook.Sheets("Print version").Visible = True
Call Color
Call MagicButton
Call exportpdfthisfile
ActiveWorkbook.Sheets("Filling form").Activate
ActiveWorkbook.Sheets("Print version").Visible = False
Application.ScreenUpdating = True
End Sub