VBA - Copy information to new workbook - excel

I'm trying to do something that sounds incredibly simple but I can't figure out how to fit it into existing VBA code. The code below cycles through a pivot table 1 item at a time and copies that pivot table data out to a new workbook and emails to the staff member
All i need to add in is for it to copy (just values and formatting) a 13x2 table in the range E15:S16 on the same sheet as the pivot table, into the new workbook in the tab I've named "Monthly Forecast". with the loops etc i'm not sure how to get this into the code so it copies the pivot data and then the monthly forecast into the separate tab
Hope that makes sense, any help would be wonderful :)
Option Explicit
Sub PivotSurvItems()
Dim i As Integer
Dim sItem As String
Dim sName As String
Dim sEmail As String
Dim OutApp As Object
Dim OutMail As Object
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.DisplayAlerts = False
With ActiveSheet.PivotTables("PivotTable1")
.PivotCache.MissingItemsLimit = xlMissingItemsNone
With .PivotFields("Staff")
'---hide all items except item 1
.PivotItems(1).Visible = True
For i = 2 To .PivotItems.Count
.PivotItems(i).Visible = False
Next
For i = 1 To .PivotItems.Count
.PivotItems(i).Visible = True
If i <> 1 Then .PivotItems(i - 1).Visible = False
sItem = .PivotItems(i)
ActiveSheet.PivotTables("PivotTable1").PivotSelect "", xlDataAndLabel, True
Selection.Copy
Workbooks.Add
With ActiveWorkbook
.Sheets(1).Cells(1).PasteSpecial _
Paste:=xlPasteValuesAndNumberFormats
Worksheets("Sheet1").Columns("A:R").AutoFit
ActiveSheet.Range("A2").AutoFilter
sName = Range("C" & 2)
sEmail = Range("N" & 2)
Columns(1).EntireColumn.Delete
Columns(2).EntireColumn.Delete
Columns(2).EntireColumn.Delete
Columns(2).EntireColumn.Delete
Columns(10).EntireColumn.Delete
ActiveSheet.Name = "FCW"
Sheets.Add(After:=Sheets(Sheets.Count)).Name = "Monthly Forecast"
Worksheets("FCW").Activate
'create folder
On Error Resume Next
MkDir "C:\Temp\FCW" & "\" & sName
On Error GoTo 0
.SaveAs "C:\Temp\FCW" & "\" & sName & "\" & sItem & " " & Format(Now(), "DD-MM-YYYY") & ".xlsx", _
FileFormat:=xlOpenXMLWorkbook
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = sEmail
.CC = ""
.BCC = ""
.Subject = "Planning Spreadsheet"
.Attachments.Add ActiveWorkbook.FullName
.Send
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
.Close
End With
Next i
End With
End With
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.DisplayAlerts = True
End Sub

Instead of changing visibility and cycling through all the items in the pivot table, assign the values to a 'table' (a range) and pass it to where you want it to go (it's much faster than using Excel's .copy and .PasteSpecial in VBA.
Also, I suggest that you copy all the data to an 'outputs' worksheet in the same workbook. When all the data has been copied, export that specific outputs worksheet into a new workbook. This way you avoid copying and pasting data between two different workbooks which can be prone to errors.
In your code, I would remove everything from the item cycling down until the Temp folder creation and replace it with something like the following:
'Copy values
Set rStartCell = ActiveSheet.Range("A1") 'Specify the top-left corner cell of the data you wish to copy
Set rTable_1 = ActiveSheet.Range(rStartCell, ActiveSheet.Range("Z" & rStartCell.End(xlDown).Row)) 'Change the Z column to the last column of the data you wish to copy. You can automate this by using something like Range(A1).end(xltoright).columns.count formula to grab the number of columns.
Debug.Print "rTable_1: " & rTable_1.Address & " -> " & rTable_1.Rows.Count & " x " & rTable_1.Columns.Count 'good to test exactly what you're copying
'Paste Values
Set rStartCell = Outputs.Range("A1") 'Change A1 to the cell of where you want to paste on the Outputs worksheet in your original workbook.
Set rTable_2 = Outputs.Range(rStartCell, rStartCell.Offset(rTable_1.Rows.Count - 1, rTable_1.Columns.Count - 1))
Debug.Print "rTable_2: " & rTable_2.Address & " -> " & rTable_2.Rows.Count & " x " & rTable_2.Columns.Count
rTable_2.Value = rTable_1.Value
rTable_1.Copy
rTable_2.PasteSpecial Paste:=xlPasteFormats 'to copy/paste those formats you need
'Copy Worksheet and open it in a new workbook
ThisWorkbook.Sheets("NAME OF OUTPUTS SHEET").Copy 'Using ThisWorkbook to point to the workbook holding this code.
ActiveSheet.Name = "FCW"
You can use this method to copy/paste that other table mentioned as well.

Related

EXCEL- Editing Excel's before copying to a new sheet with VBA

I have between 800 excels files that I need to transfer over to one sheet but before the transfer, I need to add a column ("A:A") and copy one cell value (before column added ("C1") after column ("D1")) and use column ("C:C") to get the range it would need to be pasted in column("A:A")
I have done the code already but struggling to add this on. If anyone can help that would be amazing.
Sub LoopThrough()
Dim MyFile As String, Str As String, MyDir As String
Dim sh As Worksheet, MasterRange As Range, TempWB As Workbook, TempSH As Worksheet, TempRng As Range, TempRow As Range
Dim NewMasterLine As Long
Dim StartTime As Double
Dim MinutesElapsed As String
StartTime = Timer
On Error GoTo ErrorHandler
Set sh = ThisWorkbook.Worksheets("Sheet1")
' Change address to suite
MyDir = "C:\"
MyFile = Dir(MyDir & "*.xls")
ChDir MyDir
' The following lines will put excel in a state similar to "frozen" mode. This will increase the code performance, as CPU will solely focus on performing
' the operations required by the code and not on showing the changes happening on excel
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim x As Long
x = 0
' Here starts the loop related to the files in folder
Do While MyFile <> ""
'TempWB is a Worksheet object - will be the importing worksheet. TempRng is the used range in sheet 1 of the workbook
Set TempWB = Workbooks.Open(FileName:=MyFile, UpdateLinks:=False, Password:=CalcPassword(MyFile))
Columns(1).Insert
Range("c2").Copy Range("A4:A10000")
Set TempSH = TempWB.Worksheets(1)
Set TempRng = TempSH.Range("A1:DB" & TempSH.Range("A" & TempSH.Rows.Count).End(xlUp).Row)
TempRng.Range("A:A").Insert ' This is where I tried to add in the extra column
TempRng.Range("A1").Value = TempRng.Range("D1").Value ' Tried doing this as a test but still pasted as if no changes had been made????
'NewMasterLine is the last used row (+1) of the Master Workbook (It is basically where the new rows will start to be imported)
NewMasterLine = sh.Range("A" & sh.Rows.Count).End(xlUp).Row
If NewMasterLine > 1 Then NewMasterLine = NewMasterLine + 1
'This will loop through all the rows of the range to be imported, checking the first column.
' If the value in the second column is work-xne-ams, will import the single row in the master workbook
For Each TempRow In TempRng.Rows
If Left(TempRow.Cells(1, 2).Value, 5) = "SHIFT" Or TempRow.Row < 4 Then
'If TempRow.Cells(1, 2).Value = "SHIFT--1" Or TempRow.Row < 4 Then
Set MasterRange = sh.Range("A" & NewMasterLine & ":DA" & NewMasterLine)
MasterRange.Value = TempRow.Value
NewMasterLine = NewMasterLine + 1
End If
Next
TempWB.Close savechanges:=False
MyFile = Dir()
x = x + 1
ThisWorkbook.Worksheets("PWD").Range("H2") = x
Loop
ErrorHandler:
If Err.Number <> 0 Then MsgBox "An error occurred." & vbNewLine & vbNewLine & "Last file that was attempted to be opened: " & MyFile & vbNewLine & vbNewLine & Err.Description
Application.ScreenUpdating = True
Application.DisplayAlerts = True
MinutesElapsed = Format((Timer - StartTime) / 86400, "hh:mm:ss")
MsgBox "This code ran successfully in " & MinutesElapsed & " minutes", vbInformation
End Sub
Function CalcPassword(FileName As String) As String
CalcPassword = ""
On Error Resume Next
Dim TheFile As String: TheFile = Split(Split(FileName, "\")(UBound(Split(FileName, "\"))), ".")(0)
Dim PWD As Range: Set PWD = ThisWorkbook.Worksheets("PWD").ListObjects("PWD").DataBodyRange
CalcPassword = WorksheetFunction.VLookup(TheFile, PWD, 5, False)
End Function

How to attach an Excel sheet to an Outlook email?

I'm trying to fix one issue which is attaching a file.
I have a TABLE with list of people and their names and a condition(Y/N) column.
Column 1(Name) Column 2(Email) Column 3 (Condition Y/N)
I want to send emails to all people in the TABLE whose name matches with the unique values (name) in one of the columns in Sheet 1.
So I want something that looks up the column in Sheet 1 and maybe changes the Condition to Y in the TABLE for all unique names found in that Column in Sheet 1.(I can FILTER my TABLE in POWER QUERY to show only the rows with Condition "Y").
When the SINGLE email pops up (with the all people in the "To",) I want Sheet 1 or Sheet 2 to be attached to the email.
Option Explicit
Public Sub SendEmail()
' For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
' Working in Office 2000-2016
' Adapted by Ricardo Diaz ricardodiaz.co
Dim OutApp As Object
Dim OutMail As Object
Dim sourceTable As ListObject
Dim evalRow As ListRow
Dim counter As Long
Dim toArray() As Variant
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
Set sourceTable = Range("Table6").ListObject ' -> Set the table's name
On Error GoTo cleanup
' Loop through each table's rows
For Each evalRow In sourceTable.ListRows
If evalRow.Range.Cells(, 2).Value Like "?*#?*.?*" And _
LCase(evalRow.Range.Cells(, 3).Value) = "yes" Then
ReDim Preserve toArray(counter)
toArray(counter) = evalRow.Range.Cells(, 2).Value
counter = counter + 1
End If
Next evalRow
' Setup the email
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
' Add gathered recipients
For counter = 0 To UBound(toArray)
.Recipients.Add (toArray(counter))
Next counter
.Subject = "Reminder"
.Body = "Dear All" _
& vbNewLine & vbNewLine & _
"Please comply with the transfers in the attached file. " & _
"Look up for your store and process asap."
'You can add files also like this
'.Attachments.Add ("C:\test.txt") ' -> Adjust this path
.Display ' -> Or use Display
End With
On Error GoTo 0
Set OutMail = Nothing
cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
Code to Attach sheet 1 (doesn't work)
file_name_import = Format(Now, "yyyy-mm-dd hh-mm-ss")
file_name_import = file_name_import & " - File 1.xlsx"
Worksheets("Sheet 1").Copy
ChDir "H:\Folder 1\Folder 2\Folder 3\Folder 4\"
ActiveWorkbook.SaveAs Filename:= _
"H:\Folder 1\Folder 2\Folder 3\Folder 4\File 1" & file_name_import, _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
.Attachments.Add "H:\Folder 1\Folder 2\Folder 3\Folder 4\File 1\" & file_name_import
I want to add code so my email pops up (with all required people in "To" and) with the attachment.
Option Explicit ' Consider this mandatory
' Tools | Options | Editor tab
' Require Variable Declaration
Public Sub AttachFileToEmail()
Dim OutApp As Object
Dim OutMail As Object
Dim sourceTable As ListObject
Dim evalRow As ListRow
Dim counter As Long
Dim toArray() As Variant
Dim strDir As String
Dim file_name_import As String
Dim fName As String
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
' Excel details not recreated, not needed for this question
file_name_import = Format(Now, "yyyy-mm-dd hh-mm-ss")
file_name_import = file_name_import & " - File 1.xlsx"
' Subscript out of range error would be bypassed due to poor error handling
'Worksheets("Sheet 1").Copy
Worksheets("Sheet1").Copy
' Trailing backslash error would be bypassed due to poor error handling
'ChDir "H:\Folder 1\Folder 2\Folder 3\Folder 4\"
strDir = "C:\Folder 1\Folder 2\Folder 3\Folder 4\"
Debug.Print strDir
' Backslash already at end of strDir
fName = strDir & "File 1" & file_name_import
Debug.Print fName
ActiveWorkbook.SaveAs FileName:=fName, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
' Setup the email
Set OutMail = OutApp.CreateItem(0)
' Do not use On Error Resume Next without a specific reason for bypassing errors
' Instead fix the errors now that you can see them
With OutMail
' Excel details not recreated, not needed for this question
.Subject = "Reminder"
.Body = "Dear All" _
& vbNewLine & vbNewLine & _
"Please comply with the transfers in the attached file. " & _
"Look up for your store and process asap."
.Attachments.Add fName
.Display
End With
Set OutMail = Nothing
cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
The idea here is to copy the sheet to a new file and save it in you temp folder. Then attach it to your email
Option Explicit
Public Sub SendEmail()
' For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
' Working in Office 2000-2016
' Attachment code based on: http://www.vbaexpress.com/kb/getarticle.php?kb_id=326
' Adapted by Ricardo Diaz ricardodiaz.co
Dim OutApp As Object
Dim OutMail As Object
Dim sourceTable As ListObject
Dim evalRow As ListRow
Dim newBook As Workbook
Dim newBookName As String
Dim counter As Long
Dim toArray() As Variant
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
Set sourceTable = Range("Table1").ListObject
On Error GoTo Cleanup
' Save current file to temp folder (delete first if exists)
ThisWorkbook.Worksheets("Sheet1").Copy
Set newBook = ActiveWorkbook
newBookName = "AttachedSheet.xlsx"
On Error Resume Next
Kill Environ("temp") & newBookName
On Error GoTo 0
Application.DisplayAlerts = False
newBook.SaveAs Environ("temp") & newBookName
Application.DisplayAlerts = True
' Loop through each table's rows
For Each evalRow In sourceTable.ListRows
If evalRow.Range.Cells(, 2).Value Like "?*#?*.?*" And LCase(evalRow.Range.Cells(, 3).Value) = "yes" Then
ReDim Preserve toArray(counter)
toArray(counter) = evalRow.Range.Cells(, 2).Value
counter = counter + 1
End If
Next evalRow
' Setup the email
Set OutMail = OutApp.CreateItem(0)
With OutMail
' Add gathered recipients
For counter = 0 To UBound(toArray)
.Recipients.Add (toArray(counter))
Next counter
.Subject = "Reminder"
.Body = "Dear All" _
& vbNewLine & vbNewLine & _
"Please contact us to discuss bringing " & _
"your account up to date"
'You can add files also like this
.Attachments.Add newBook.FullName ' -> Adjust this path
.Display ' -> Or use Display
End With
Set OutMail = Nothing
Cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
Let me know if it works

Attach files to an email using Excel VBA

I am trying to save two worksheets in a workbook as separate files to company network locations and then attach those files to an email.
Sub Test_Module_Peter()
'
Dim OutApp As Object
Dim OutMail As Object
Dim SPpath As String
Dim SCpath As String
Dim SPfilename As String
Dim SCfilename As String
Dim SPFullFilePath As String
Dim SCFullFilePath As String
Dim wb As Workbook
Dim Cell As Range
Application.ScreenUpdating = False
' export a copy of PER SP Form
Sheets("PER SP").Select
Sheets("PER SP").Copy
' Remove formulas from SP sheet
With ActiveSheet.UsedRange
.Cells.Copy
.Cells.PasteSpecial xlPasteValues
.Cells(1).Select
End With
Application.CutCopyMode = False
' Save a copy of the SP PER Form
SPpath = "\\UKRLTD008\Company\...\...\...\2019\"
SPfilename = "TEST - PER SP ABL90_2019 " & Range("M1")
SPFullFilePath = SPpath & SPfilename
ActiveWorkbook.SaveAs filename:=SPpath & SPfilename, FileFormat:=52
ActiveWorkbook.Close SaveChanges = True
' select ABL90 Credit Claim Master Spreadsheet
For Each wb In Application.Workbooks
If wb.Name Like "ABL90 Credit Claim Master*" Then
wb.Activate
End If
Next
' export a copy of PER SC Form
Sheets("PER SC").Select
Sheets("PER SC").Copy
' Remove formulas from SC sheet
With ActiveSheet.UsedRange
.Cells.Copy
.Cells.PasteSpecial xlPasteValues
.Cells(1).Select
End With
Application.CutCopyMode = False
' Save a copy of the SC PER Form
SCpath = "\\UKRLTD008\Company\...\...\...\2019\"
SCfilename = "TEST - PER SC ABL90_2019 " & Range("M1")
SCFullFilePath = SCpath & SCfilename
ActiveWorkbook.SaveAs filename:=SCpath & SCfilename, FileFormat:=52
ActiveWorkbook.Close SaveChanges = True
' Send the SP PER Form to RMED
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.SentOnBehalfOfName = "sales#radiometer.co.uk"
.To = "laura.valenti#radiometer.co.uk"
.CC = ""
.BCC = ""
.Subject = "RLTD PER Forms " & Range("M1")
.Body = "Hi " & vbNewLine & vbNewLine & "Please find attached ABL90 PER's" & vbNewLine & vbNewLine & "Thank you"
.Attachments.Add SPFullFilePath
.Attachments.Add SCFullFilePath
.Display
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
It saves the files, but when I try to add them as attachments to the email, the following error occurs:
Run-time error '-2147024894(80070002)': Cannot find this file. Verify the path and file name are correct.
I tried to save the path and filename together as FullFilePath for each file but it doesn't seem to work, can anyone tell me why?

Paste special required in macro transferring data between sheets

I have a macro set up which transfers selected rows to Sheet2 to pass information to another department.
This is a shared spreadsheet and I'm having issues with the macro overwriting conditional formatting on Sheet2 when passed over.
Would anyone be able to help with altering the macro below to paste values only which I hope will not overwrite any conditional formatting already applied on Sheet 2.
Sub Pass_to_xDepartment()
Application.EnableEvents = False
On Error GoTo Whoops
'Declare variables
Dim sht1 As Worksheet
Dim sht2 As Worksheet
Dim lastRow As Long
Dim lastRow2 As Long
Dim WSheet As Variant
Dim DTable As Variant
Dim Sendrng As Range
Dim sht3 As Worksheet
'MsgBox when passing over work
If MsgBox("Do you want to pass the selected work to xDepartment?" & vbNewLine & vbNewLine & "Please ensure selected work is complete." & vbNewLine & vbNewLine & "This will generate an automatic email to xDepartment.", vbYesNo, "Pass to xDepartment") = vbNo Then Exit Sub
For Each WSheet In ActiveWorkbook.Worksheets
If WSheet.AutoFilterMode Then
If WSheet.FilterMode Then
WSheet.ShowAllData
End If
End If
For Each DTable In WSheet.ListObjects
If DTable.ShowAutoFilter Then
DTable.Range.AutoFilter
DTable.Range.AutoFilter
End If
Next DTable
Next WSheet
'Set variables
Set sht1 = Sheets("yDepartment")
Set sht2 = Sheets("xDepartment")
'Move row to destination sheet & Delete source row
lastRow = sht2.Range("A" & sht2.Rows.Count).End(xlUp).Row
'Select Entire Row.Resize(ColumnSize:=12)
Intersect(Selection.EntireRow, Selection.Parent.Columns("N")).Value = Date
With Intersect(Selection.EntireRow, Selection.Parent.Range("A:N"))
.Copy Destination:=sht2.Range("A" & lastRow + 1)
lastRow2 = sht2.Range("A" & sht2.Rows.Count).End(xlUp).Row
.EntireRow.Delete
End With
On Error Resume Next
Set sht3 = ActiveWorkbook.Sheets("temp")
On Error GoTo 0
If sht3 Is Nothing Then
Set sht3 = ActiveWorkbook.Sheets.Add(After:=Worksheets(Worksheets.Count))
sht3.Name = "temp"
Else
sht3.UsedRange.Clear
End If
'Note: if the selection is one cell it will send the whole worksheet
Set Sendrng = sht2.Range("A" & (lastRow + 1) & ":N" & lastRow2)
Sendrng.Copy Destination:=sht3.Range("A1")
On Error GoTo StopMacro
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Create the mail and send it
sht3.Activate
lastRow2 = sht3.Range("A" & sht3.Rows.Count).End(xlUp).Row
Set Sendrng = sht3.Range("A1:N" & lastRow2)
With Sendrng
ActiveWorkbook.EnvelopeVisible = True
With .Parent.MailEnvelope
' Set the optional introduction field thats adds
' some header text to the email body.
.Introduction = "Dear xDepartment," & vbNewLine & vbNewLine & "The following work has been completed." & vbNewLine & vbNewLine & "Please see the shared spreadsheet for further details." & vbNewLine & vbNewLine & "Kind regards," & vbNewLine & "yDepartment" & vbNewLine
With .Item
.To = "email"
.CC = "email"
.BCC = ""
.Subject = "New work passed over from yDepartment"
.Send
End With
End With
End With
StopMacro:
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
ActiveWorkbook.EnvelopeVisible = False
Worksheets("yDepartment").Activate
MsgBox ("Tours have been passed to xDepartment.")
Whoops:
Application.EnableEvents = True
End Sub

Userform data to populate specific tables on worksheet

I have been searching high and low and have come up with some results but not what I'm trying to accomplish.
I have two different userforms, one to create a Purchase Order, another to create a Change Order. Depending on the userform that is selected, once data is entered and the command button is used, I need the data to populate either Table1 (for Purchase Orders from the POUserform) or Table2 (for Change Orders from the COUserform). Both tables are on the same worksheet. Is this even possible???
Below is the code I currently have - it always wants to populate the same Table no matter what userform I am running.
Note that the code for Userform 1 and Userform 2 are exactly the same with the exception of "Table1" and "Table 2".
Private Sub SendCOButton_Click()
Dim xSht As Worksheet
Dim xFileDlg As FileDialog
Dim xFolder As String
Dim xYesorNo As Integer
Dim xOutlookObj As Object
Dim xEmailObj As Object
Dim xUsedRng As Range
Dim rng As Range
Set rng = ActiveSheet.ListObjects("Table2").Range
Dim LastRow As Long
Dim iRow As Long
Dim WS1 As Worksheet, WS2 As Worksheet, WS3 As Worksheet
Set WS1 = Worksheets("Original Contracts")
Set WS2 = Worksheets("Purchase Order Template")
Set WS3 = Worksheets("Project Snapshot")
'find first empty row in database
iRow = WS1.Cells.Find(What:="*", SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlValues).Row + 1
LastRow = WS3.Cells.Find(What:="*", SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlValues).Row + 1
If WorksheetFunction.CountIf(WS3.Range("A1:A5000", WS3.Cells(LastRow, 1)),
Me.CONo.Value) > 0 Then
MsgBox "Duplicate Change Order Number!", vbCritical
Exit Sub
End If
'copy the data to the database
'use protect and unprotect lines,
' with your password
' if worksheet is protected
With WS1
End With
With WS2
.Range("H1").Value = Me.CONo.Value
.Range("B6").Value = Me.COTradeList.Value
.Range("H6").Value = Me.COAttn.Value
.Range("B7").Value = Me.COEmail.Value
.Range("H7").Value = Me.COPhone.Value
.Range("H16").Value = Me.COPrice1.Value
End With
With WS3
rng.Parent.Cells(LastRow, 1).Value = CONo.Value
rng.Parent.Cells(LastRow, 2).Value = COTradeList.Value
rng.Parent.Cells(LastRow, 3).Value = COItems.Value
rng.Parent.Cells(LastRow, 4).Value = CODescription1.Value
rng.Parent.Cells(LastRow, 5).Value = COPrice1.Value
rng.Parent.Cells(LastRow, 6).Value = CODateIssued.Value
End With
Set xSht = Worksheets("Purchase Order Template")
Set xFileDlg = Application.FileDialog(msoFileDialogFolderPicker)
If xFileDlg.Show = True Then
xFolder = xFileDlg.SelectedItems(1)
Else
MsgBox "You must specify a folder to save the PDF into." & vbCrLf &
vbCrLf & "Press OK to exit this macro.", vbCritical, "Must Specify
Destination Folder"
Exit Sub
End If
xFolder = xFolder + "\" & Worksheets("Purchase Order
Template").Range("B9").Value & " - PO No. " & Worksheets("Purchase Order
Template").Range("G1").Value & " - " & Worksheets("Purchase Order
Template").Range("B6").Value & ".pdf"
'Check if file already exist
If Len(Dir(xFolder)) > 0 Then
xYesorNo = MsgBox(xFolder & " already exists." & vbCrLf & vbCrLf & "Do
you want to overwrite it?", _
vbYesNo + vbQuestion, "File Exists")
On Error Resume Next
If xYesorNo = vbYes Then
Kill xFolder
Else
MsgBox "if you don't overwrite the existing PDF, I can't continue." _
& vbCrLf & vbCrLf & "Press OK to exit this macro.",
vbCritical, "Exiting Macro"
Exit Sub
End If
If Err.Number <> 0 Then
MsgBox "Unable to delete existing file. Please make sure the file is
not open or write protected." _
& vbCrLf & vbCrLf & "Press OK to exit this macro.",
vbCritical, "Unable to Delete File"
Exit Sub
End If
End If
Set xUsedRng = xSht.UsedRange
If Application.WorksheetFunction.CountA(xUsedRng.Cells) <> 0 Then
'Save as PDF file
xSht.ExportAsFixedFormat Type:=xlTypePDF, FileName:=xFolder,
Quality:=xlQualityStandard
'Create Outlook email
Set xOutlookObj = CreateObject("Outlook.Application")
Set xEmailObj = xOutlookObj.CreateItem(0)
Set xSht = Worksheets("Purchase Order Template")
With xEmailObj
.Display
.To = Worksheets("Purchase Order Template").Range("B7").Value
.CC = ""
.BCC = ""
.Subject = Worksheets("Purchase Order Template").Range("E9").Value & "
- " & "PO# " & Worksheets("Purchase Order Template").Range("G1").Value &
" - " & Worksheets("Purchase Order Template").Range("B6").Value
.Attachments.Add xFolder
If DisplayEmail = False Then
'.Send
End If
End With
Else
MsgBox "The active worksheet cannot be blank"
Exit Sub
End If
Unload Me
End Sub
We have NO idea on the layout of your sheets, but we can try to get a picture of what's happening using the code:
This section appears to be the part which (I assume) you change to refer to the appropriate table:
Dim rng As Range
Set rng = ActiveSheet.ListObjects("Table2").Range
You then, later in the code, write to a sheet using:
With WS3
rng.Parent.Cells(LastRow, 1).Value = CONo.Value
rng.Parent.Cells(LastRow, 2).Value = COTradeList.Value
rng.Parent.Cells(LastRow, 3).Value = COItems.Value
rng.Parent.Cells(LastRow, 4).Value = CODescription1.Value
rng.Parent.Cells(LastRow, 5).Value = COPrice1.Value
rng.Parent.Cells(LastRow, 6).Value = CODateIssued.Value
End With
Let's look at what you're doing here by breaking down a couple of the lines:
Firstly, your With/End With are irrelevant, you're not using WS3 at all here. They can go. They don't do any harm because they don't do anything. Everything inside this wrapper refers to everything in relation to rng anyway.
More importantly though, you're writing to cells using rng.Parent.Cells(LastRow, X)
So you refer to the table's range (called rng), then you go to it's .Parent which will be the sheet that Table2 sits on and then from cell A1 you find the cell using LastRow and x.
Now previously, LastRow examines the WS3 sheet to find the last cell/row used, not the rng or Table2 - so you'll be writing to the row based on WS3, regardless of where rng sits.
If you can advise WHERE Table1 and Table2 are (which sheet, top left cell address) I think I might be able to update this but right now I'd be guessing.

Resources