VBA Copy two ranges and combine them, then save in text file - vba

I need to copy two ranges of cells from two separate worksheets in one file, and combine them then save then into a text file. I only know how to save one range of cells into txt. file like the code below.
Dim LastRow As Long
Dim Count As Range
LastRow = Range("K" & Sheets("Reports").Rows.Count).End(xlUp).Row
Dim wbText As Workbook
Dim wsReports As Worksheet
Set wbText = Workbooks.Add
Set wsReports = ThisWorkbook.Worksheets("Reports")
With wsReports
.Range("Q2" & ":Q" & LastRow).Copy wbText.Sheets(1).Range("A1")
End With
Application.DisplayAlerts = False
With wbText
.SaveAs Filename:="P:\Newsletter Email.txt", FileFormat:=xlText
.Close False
End With
This code copies column F in sheet Reports in to the text file, but I also need to copy column L from sheet Reports1 into the text file. I know
RangeCombined = Union(Range1, Range2)
Could combine two ranges, how can I integrate this code into this situation?
Thanks in advance.

Try
Dim LastRow As Long
Dim LastRow1 As Long
Dim Count As Range
Dim wbText As Workbook
Dim wsReports As Worksheet
Dim wsReports1 As Worksheet
Set wbText = Workbooks.Add
Set wsReports = ThisWorkbook.Worksheets("Reports")
Set wsReports1 = ThisWorkbook.Worksheets("Reports1")
LastRow = wsReports.Range("K" & wsReports.Rows.Count).End(xlUp).Row
LastRow1 = wsReports1.Range("K" & wsReports1.Rows.Count).End(xlUp).Row
wsReports.Range("Q2" & ":Q" & LastRow).Copy wbText.Sheets(1).Range("A1")
wsReports1.Range("F2" & ":F" & LastRow1).Copy wbText.Sheets(1).Range("B1")
Application.DisplayAlerts = False
With wbText
.SaveAs Filename:="P:\Newsletter Email.txt", FileFormat:=xlText
.Close False
End With
This will copy column Q of Reports into column A of the output, and column F of Reports1 into column B of the output.
Alternatively, if you want column F of Reports1 to appear below column Q of Reports, change the Copy statements to be:
wsReports.Range("Q2" & ":Q" & LastRow).Copy wbText.Sheets(1).Range("A1")
wsReports1.Range("F2" & ":F" & LastRow1).Copy wbText.Sheets(1).Range("A" & LastRow)
(If there are the same number of rows in both Reports and Reports1, the above can be simplified a bit.)

I think the best way is to save the file to a path while printing to it. Try this
Dim FilePath As String
Dim lCol As String
Dim fCol As String
Dim fRange As String
Dim lRange As String
Dim wsReports As Worksheet
Dim wsReports1 As Worksheet
Set wsReports = ThisWorkbook.Worksheets("Reports")
Set wsReports1 = ThisWorkbook.Worksheets("Reports1")
FilePath = "P:\Newsletter Email.txt"
fRange = "F2:F" & LastRow
lRange = "L2:L" & LastRow
'Will create the file if it does not exist
Open FilePath For Output As #1
With wsReports
.Range("Q2" & ":Q" & lastrow).Copy wbText.Sheets(1).Range("A1")
For i = 0 To lastrow
fCol = .Cells(i, "F")
Print #1, fCol
Next i
End With
With wsReports1
For i = 0 To lastrow
lCol = .Cells(i, "L")
Print #1, lCol
Next i
End With
'Make sure to close it or you'll have difficulties opening the file
Close #1

Related

VBA to VLOOKUP a value from a pivot table to return value in multiple columns in the output sheet

I have two sheets, one is sheet Data Sheet with a pivot table with data of different companies. I have another sheet Output Sheet with few column headings from data sheet, I want to vlookup different column headings using the Company ID. I have found the below code and it works fine for mapping company name but has the following issues
The formula runs till 100000 rows even if the companyID is available only till 9555 row, and there after displays #N/A
How to make this formula lookup other column headings like Segment, Sector Etc.
Columns Heading that needs to be mapped:
Sub MakeFormulas()
Dim SourceLastRow As Long
Dim OutputLastRow As Long
Dim sourceBook As Workbook
Dim sourceSheet As Worksheet
Dim outputSheet As Worksheet
Application.ScreenUpdating = True
'Where is the source workbook?
Set sourceBook = Workbooks.Open("C:\Users\AAA\Desktop\NewFolder\Automation\07-Macro.xlsb")
'what are the names of our worksheets?
Set sourceSheet = sourceBook.Worksheets("TERFYTDPR")
Set outputSheet = ThisWorkbook.Worksheets("All TMS-Data")
'Determine last row of source
With sourceSheet
SourceLastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
With outputSheet
'Determine last row in col B
OutputLastRow = .Cells(.Rows.Count, "B").End(xlUp).Row + 1
'Apply our formula
.Range("B2:B10000" & OutputLastRow).Formula = _
"=VLOOKUP(A2,'[" & sourceBook.Name & "]" & sourceSheet.Name & "'!$A$2:$B$" & SourceLastRow & ",2,0)"
OutputLastRow = .Cells(.Rows.Count, "B").End(xlUp).Row + 1
End With
'Close the source workbook, don't save any changes
sourceBook.Close False
Application.ScreenUpdating = True
End Sub
We don't know the layout of your data on the Worksheet you are doing the Vlookup against, but just thought I would explain the Vlookup:
=VLOOKUP(A2,'[" & sourceBook.Name & "]" & sourceSheet.Name & "'!$A$2:$B$" & SourceLastRow & ",2,0)"
The last number 2 on the line of code above refers to the column number you would like to return if the Contents of A2 match, you can alter this to get another column number, such as 3 for the third column, but you should also change the range to lookup from $A$2:$B$, to include the other columns.
So for example if your Segment column is in Column C, you would alter your vlookup as such:
=VLOOKUP(A2,'[" & sourceBook.Name & "]" & sourceSheet.Name & "'!$A$2:$C$" & SourceLastRow & ",3,0)"
I would also re-write your code as follows:
Sub MakeFormulas()
Dim SourceLastRow As Long, OutputLastRow As Long, i As Long
Dim sourceBook As Workbook
Dim sourceSheet As Worksheet, outputSheet As Worksheet
Application.ScreenUpdating = True
'Where is the source workbook?
Set sourceBook = Workbooks.Open("C:\Users\AAA\Desktop\NewFolder\Automation\07-Macro.xlsb")
'what are the names of our worksheets?
Set sourceSheet = sourceBook.Worksheets("TERFYTDPR")
Set outputSheet = ThisWorkbook.Worksheets("All TMS-Data")
'Determine last row of source
SourceLastRow = sourceSheet.Cells(sourceSheet.Rows.Count, "A").End(xlUp).Row
'Determine last row in col B
OutputLastRow = outputSheet.Cells(outputSheet.Rows.Count, "A").End(xlUp).Row
'Apply our formula
For i = 2 To OutputLastRow
outputSheet.Range("B" & i).Formula = "=VLOOKUP(A" & i & ",'[" & sourceBook.Name & "]" & sourceSheet.Name & "'!$A$2:$C$" & SourceLastRow & ",2,0)"
outputSheet.Range("C" & i).Formula = "=VLOOKUP(A" & i & ",'[" & sourceBook.Name & "]" & sourceSheet.Name & "'!$A$2:$C$" & SourceLastRow & ",3,0)"
'if segment is found in column C, and you also want the results in column C the line above will return the desired value
Next i
'Close the source workbook, don't save any changes
sourceBook.Close False
Application.ScreenUpdating = True
End Sub
UPDATE:
To do the same without a loop:
Sub MakeFormulas()
Dim SourceLastRow As Long, OutputLastRow As Long, i As Long
Dim sourceBook As Workbook
Dim sourceSheet As Worksheet, outputSheet As Worksheet
Application.ScreenUpdating = True
'Where is the source workbook?
Set sourceBook = Workbooks.Open("C:\Users\AAA\Desktop\NewFolder\Automation\07-Macro.xlsb")
'what are the names of our worksheets?
Set sourceSheet = sourceBook.Worksheets("TERFYTDPR")
Set outputSheet = ThisWorkbook.Worksheets("All TMS-Data")
'Determine last row of source
SourceLastRow = sourceSheet.Cells(sourceSheet.Rows.Count, "A").End(xlUp).Row
'Determine last row in col B
OutputLastRow = outputSheet.Cells(outputSheet.Rows.Count, "A").End(xlUp).Row
'Apply our formula
outputSheet.Range("B2:B:" & OutputLastRow).Formula = "=VLOOKUP(A2,'[" & sourceBook.Name & "]" & sourceSheet.Name & "'!$A$2:$C$" & SourceLastRow & ",2,0)"
outputSheet.Range("C2:C" & OutputLastRow).Formula = "=VLOOKUP(A2,'[" & sourceBook.Name & "]" & sourceSheet.Name & "'!$A$2:$C$" & SourceLastRow & ",3,0)"
'if segment is found in column C, and you also want the results in column C the line above will return the desired value
'Close the source workbook, don't save any changes
sourceBook.Close False
Application.ScreenUpdating = True
End Sub
As I understand you want to populate the VLOOKUP formula into the table but only for the rows where is a data?
Assuming that Column "A" - CompanyID and "B" - Company Name is always populated and there are no gaps between the records you can make excel to drag the formula for you
Here is the code for you
Sub test()
Dim maxRow As Long
Dim DataWS As Worksheet
Dim lookupWS As Worksheet
'Set your data sheet
Set DataWS = Worksheets("Sheet1")
'Set your lookup sheet
Set lookupWS = Worksheets("Sheet2")
maxRow = lookupWS.Range("A1").End(xlDown).Row
'Populate formula
'Company Name
lookupWS.Range("B2").Formula = "=VLOOKUP($A2," & DataWS.Name & "!$A:$F,2,FALSE)" 'Make sure you change "2" to correct value in your case
'Segment
lookupWS.Range("C2").Formula = "=VLOOKUP($A2," & DataWS.Name & "!$A:$F,3,FALSE)" 'Make sure you change "3" to correct value in your case
'Sector
lookupWS.Range("D2").Formula = "=VLOOKUP($A2," & DataWS.Name & "!$A:$F,4,FALSE)" 'Make sure you change "4" to correct value in your case
'Channel
lookupWS.Range("E2").Formula = "=VLOOKUP($A2," & DataWS.Name & "!$A:$F,5,FALSE)" 'Make sure you change "5" to correct value in your case
'Account Type
lookupWS.Range("F2").Formula = "=VLOOKUP($A2," & DataWS.Name & "!$A:$F,6,FALSE)" 'Make sure you change "6" to correct value in your case
'Drag formula
Range("B2:F2").AutoFill Destination:=Range("B2:F" & maxRow), Type:=xlFillCopy
End Sub
Make sure you change your range arrays appropriately and it should work for you.

VBA - Vlookup returns on development but not when added to ribbon

I've a strange problem.
the following code will run using F8 or pressing the run button on the development module.
But when added to the excel ribbon as a macro by the following process the vlookup will return #N/A :
1.right click on the excel toolbar > customize the ribbon
choose macro commands
add it to a new group.
the code is :
Sub Compare()
'set primary Workbook
'find last cell'
Dim WS As Worksheet
Dim LastCell As Range
Dim LastCellRowNumber As Long
Set WS = Worksheets("Sheet1")
With WS
Set LastCell = .Cells(.Rows.Count, "A").End(xlUp)
LastCellRowNumber = LastCell.Row
'MsgBox (LastCell.Row)
End With
'Adding Index Column
Columns("A:A").Select
Selection.Insert Shift:=xlToRight
[A2].Formula = "=G2&H2"
Range("A2:A" & LastCellRowNumber).FillDown
'adding headers
[Ag1].Value = "Resale"
[Ah1].Value = "Cost"
[Ai1].Value = "disti"
'set primary Workbook
Dim Pri As Workbook
Set Pri = ActiveWorkbook
'open company quotes
Workbooks.Open ("R:\company\DATA\company quotes.xlsx")
'find last cell'
Dim WSq As Worksheet
Dim LastCellq As Range
Dim LastCellRowNumberq As Long
Set WSq = Worksheets("Quote Summary")
With WSq
Set LastCellq = .Cells(.Rows.Count, "A").End(xlUp)
LastCellRowNumberq = LastCellq.Row
'MsgBox (LastCell.Row)
End With
Columns("A:A").Select
Selection.Insert Shift:=xlToRight
Dim quotes As Workbook
Set quotes = ActiveWorkbook
[A2].Formula = "=J2&B2"
Range("A2:A" & LastCellRowNumberq).FillDown
Pri.Activate
Dim i As Integer
For i = 2 To LastCellRowNumber
Dim result As String
Dim sheet As Worksheet
Range("AG" & i) = Application.VLookup(Sheet1.Range("A" & i), Workbooks("company quotes.xlsx").Worksheets("Quote Summary").Range("A2:AS" & LastCellRowNumberq), 17, False)
Range("AH" & i) = Application.VLookup(Sheet1.Range("A" & i), Workbooks("company quotes.xlsx").Worksheets("Quote Summary").Range("A2:AS" & LastCellRowNumberq), 19, False)
Range("Ai" & i) = Application.VLookup(Sheet1.Range("A" & i), Workbooks("company quotes.xlsx").Worksheets("Quote Summary").Range("A2:AS" & LastCellRowNumberq), 20, False)
Next i
End Sub
I've tried to fix any referencing issues I could find but you'll need to have a look through and make sure all of the Range references are prefixed with the correct Workbook and Worksheet as it wasn't too clear which worksheet they were coming from in the original code:
Sub Compare()
'Set primary Workbook
'Find last cell
Dim WS As Worksheet
Dim LastCellRowNumber As Long
Set WS = ThisWorkbook.Sheets("Sheet1")
LastCellRowNumber = WS.Cells(WS.Rows.Count, "A").End(xlUp).Row
'MsgBox (LastCell.Row)
'Adding Index Column
WS.Columns("A:A").Insert Shift:=xlToRight
WS.Range("A2:A" & LastCellRowNumber).Formula = "=G2&H2"
'adding headers
WS.Range("AG1").Value = "Resale"
WS.Range("AH1").Value = "Cost"
WS.Range("AI1").Value = "disti"
'open company quotes
Dim wbCompQuotes As Workbook
Set wbCompQuotes = Workbooks.Open ("R:\company\DATA\company quotes.xlsx")
'find last cell'
Dim wsQuoteSum As Worksheet
Dim LastCellRowNumberq As Long
Set wsQuoteSum = wbCompQuotes.Worksheets("Quote Summary")
LastCellRowNumberq = wsQuoteSum.Cells(wsQuoteSum.Rows.Count, "A").End(xlUp).Row
'MsgBox (LastCell.Row)
wsQuoteSum.Columns("A:A").Insert Shift:=xlToRight
wsQuoteSum.Range("A2:A" & LastCellRowNumberq).Formula = "=J2&B2"
Dim i As Long
For i = 2 To LastCellRowNumber
WS.Range("AG" & i) = Application.VLookup(WS.Range("A" & i), wsQuoteSum.Range("A2:AS" & LastCellRowNumberq), 17, False)
WS.Range("AH" & i) = Application.VLookup(WS.Range("A" & i), wsQuoteSum.Range("A2:AS" & LastCellRowNumberq), 19, False)
WS.Range("AI" & i) = Application.VLookup(WS.Range("A" & i), wsQuoteSum.Range("A2:AS" & LastCellRowNumberq), 20, False)
Next i
End Sub

Excel VBA code for Looping through files and copying specific data to one file

I am new to VBA and If anyone can help, I'd greatly appreciate it. I just need help in simple VBA loop in following code.
I am trying to loop through excel files in a folder and copy specific data from source Worksheet in all files to a new workbook (sheet 2). I have a code which does 70% of the job but I am having difficulty in picking some data and copying it in specific format.
Option Explicit
Const FOLDER_PATH = "C:\Temp\" 'REMEMBER END BACKSLASH
Sub ImportWorksheets()
'=============================================
'Process all Excel files in specified folder
'=============================================
Dim sFile As String 'file to process
Dim wsTarget As Worksheet
Dim wbSource As Workbook
Dim wsSource As Worksheet
Dim rowTarget As Long 'output row
Dim FirstRow As Long, LastRow As Long
FirstRow = 1
LastRow = 5
Dim RowRange As Range
rowTarget = 2
'check the folder exists
If Not FileFolderExists(FOLDER_PATH) Then
MsgBox "Specified folder does not exist, exiting!"
Exit Sub
End If
'reset application settings in event of error
On Error Goto errHandler
Application.ScreenUpdating = False
'set up the target worksheet
Set wsTarget = Sheets("Sheet2")
'loop through the Excel files in the folder
sFile = Dir(FOLDER_PATH & "*.xls*")
Do Until sFile = ""
'open the source file and set the source worksheet - ASSUMED WORKSHEET(1)
Set wbSource = Workbooks.Open(FOLDER_PATH & sFile)
Set wsSource = Sheets("DispForm") 'EDIT IF NECESSARY
'import the data
With wsTarget
For Each rw In RowRange
If wsSource.Cells(rw.Row, 1) & wsSource.Cells(rw.Row + 1, 1) = "" Then
Exit For
End If
.Range("A" & rowTarget).Value = wsSource.Range("B1").Value
.Range("B" & rowTarget).Value = wsSource.Cells(rw.Row, 2)
.Range("C" & rowTarget).Value = wsSource.Cells(rw.Row, 4)
.Range("D" & rowTarget).Value = sFile
rowTarget = rowTarget + 1
Next rw
End With
'close the source workbook, increment the output row and get the next file
wbSource.Close SaveChanges:=False
rowTarget = rowTarget + 1
sFile = Dir()
Loop
errHandler:
On Error Resume Next
Application.ScreenUpdating = True
'tidy up
Set wsSource = Nothing
Set wbSource = Nothing
Set wsTarget = Nothing
End Sub
Private Function FileFolderExists(strPath As String) As Boolean
If Not Dir(strPath, vbDirectory) = vbNullString Then FileFolderExists = True
End Function
you only copy one row of data from your source file. so you need either to have a loop inside your file loop to loop all the rows, or to have a range to select all the rows.
try something like the following:
Dim FirstRow As Long, LastRow As Long
FirstRow = 9
LastRow = 100
Set rowRange = wsSource.Range("A" & FirstRow & ":A" & LastRow)
With wsTarget
For Each rw In rowRange
If wsSource.Cells(rw.Row, 2) = "" Then
Exit For
End If
.Range("A" & rowTarget).Value = wsSource.Cells(rw.Row, 2)
.Range("B" & rowTarget).Value = wsSource.Cells(rw.Row, 3)
Next rw
End With

Excel VBA code to find a certain cell and delete a section surrounding it

I am writing a macro in Excel. Part of the code finds the cell that has "Attached Packaging" in it and then deletes the contents of a group of cells surrounding that cell.
Here is the code that currently achieves this:
Cells.Find("Attached Packaging").Activate
ActiveCell.Resize(2, 4).Select
Selection.Clear
ActiveCell.Offset(1, -1).Select
Selection.Clear
My problem now is that I, unexpectedly, have multiple cells with "Attached Packaging" in them which now also have to be deleted.
So, to summarize: I need to modify this code so It finds all "Attached Packaging" cells in a spreadsheet and deletes the group around them.
Sub clear()
Dim ws As Worksheet
Dim search As String
Dim f As Variant
Dim fRow As Long
Dim fCol As Long
search = "Attached Packaging"
Set ws = ThisWorkbook.Worksheets("Sheet4") 'change sheet as needed
With ws.Range("A1:AA1000") 'change range as needed
Set f = .Find(search, LookIn:=xlValues)
If Not f Is Nothing Then
Do
fRow = f.Row
fCol = f.Column
ws.Range(Cells(fRow, fCol), Cells(fRow + 1, fCol + 3)).clear
ws.Cells(fRow + 1, fCol - 1).clear
Set f = .FindNext(f)
Loop While Not f Is Nothing
End If
End With
End Sub
Sub clearCells()
Dim ws As Worksheet
Dim lastrow As Long, currow As Long
Dim critvalue As String
Set ws = Sheets("Sheet1")
' Change A to a row with data in it
lastrow = ws.Range("A" & Rows.Count).End(xlUp).Offset(1).Row - 1
'Change 2 to the first row to check
For currow = 2 To lastrow
critvalue = "Attached Packaging"
' Change A to the row you are looking in
If ws.Range("A" & currow).Value = critvalue Then
' Use the currow to select the row and then create an offset
ws.Range("A" & currow).offset("B" & currow - 1).clear
ws.Range("A" & currow).offset("B" & currow + 1).clear
End If
Next currow
End Sub
Make the changes needed where I commented. It should work.

using a variable name in my VBA sumif formula

I have built a code that performs a sumif on another workbook that I open using the get open filename dialogue box. I intend to use this formula daily, and hence the workbook where I intend to obtain the information and the workbook where I intend to paste the results will continue to have varying names basing on the date of the day.
I get a type mismatch on the SUMIF formula. Please help.
Sub flextab()
Dim LastCol As Integer, LastRow As Long
' Get the dimensions
With Sheets("Flex")
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
End With
'Insert a column where required.
Cells(2, LastCol - 1).EntireColumn.Insert
'Insert the date
Cells(2, LastCol - 1).Value = Date - 1
'Insert the balance sheet balances for the day
Dim wb1 As Workbook, wb2 As Workbook
Dim FileName1 As String, FileName2 As String
Dim BalSheet As Worksheet
Dim Ret1
FileName1 = ThisWorkbook.Name
'~~> Get the first File
Ret1 = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*", _
, "Please select the Balance sheet for the day")
If Ret1 = False Then Exit Sub
Set wb2 = Workbooks.Open(Ret1)
FileName2 = wb2.Name
Workbooks(FileName1).Activate
'let's get a reference to the worksheet with the source values
Set BalSheet = Workbooks(FileName2).Worksheets("Sheet1")
With Worksheets("Flex").Range(Cells(5, LastCol - 1), Cells(109, LastCol - 1))
'let's put in our SUMIF formulas
.Formula = "=SUMIF(" & BalSheet.Range("B2:B20000") & "," & Worksheets("Flex").Range("A5") & " , " & BalSheet.Range("n2:n20000") & ")"
'let's convert the formulas into values
.Value = .Value
End With
wb2.Close SaveChanges:=False
Set wb2 = Nothing
Set wb1 = Nothing
End Sub
You are adding ranges to a string, while ranges are objects. Try this:
"=SUMIF(" & BalSheet.Range("B2:B20000").Address & "," & Worksheets("Flex").Range("A5").Value & " , " & BalSheet.Range("n2:n20000").Address & ")"
instead of this:
"=SUMIF(" & BalSheet.Range("B2:B20000") & "," & worksheets("Flex").Range("A5") & " , " & BalSheet.Range("n2:n20000") & ")"
You are working with 2 workbooks, but you are using some worksheets without qualifier.
If you have focus to the wrong workbook this will fail if the workbook that is active does not have a Flex worksheet.
So change this:
Worksheets("Flex").Range(Cells(5, LastCol - 1)
to this:
wbX.Worksheets("Flex").Range(Cells(5, LastCol - 1)
where the X is the correct workbook.