Find values from a Word table in an Excel table - excel

I want to iterate through the values of a column in a table in a word file, and check if those values are in a column in a table in an Excel file. I have the following code:
Private Sub CompararColumnas_Click()
Dim wrdTbl As Table
'Set your table
With ActiveDocument
If ActiveDocument.Tables.Count >= 1 Then
Set wrdTbl = .Tables(InputBox("Table # to copy? There are " & .Tables.Count & " tables to choose from."))
End If
End With
Dim AD_UsersPath As String
AD_UsersPath = "C:\Users\" & Environ("Username") & "\Desktop\Comparar Columnas VBA\Animales.xlsx"
Dim AD_USERS As Object
Set AD_USERS = CreateObject("Excel.Application")
AD_USERS.Visible = False
AD_USERS.Application.Workbooks.Open AD_UsersPath
LastRow = ThisDocument.Tables(1).Columns(1).Cells.Count
Dim I As Integer
For I = 1 To LastRow
wVal = ThisDocument.Tables(1).Cell(I, 1)
User = AD_USERS.Cells(AD_USERS.Range("A:A").Find(What:=wVal).Row, 1).Text
wrdTbl.Cell(I, 2).Range.Text = User
Next I
End Sub
This code iterates in wVal the values from the first column in a table from Word and after that it goes to Excel to find those values in the first column of the Excel table. If it finds them, it copies the values in the second column of the word table. However, it gives me an error 91. If instead of Find(What:=wVal) I put something like Find(What:="Word") it does not give me an error and puts the word "Word" in every cell of the second column of the word table. How can I solve this?

Cell values in Word have a two-character "end of cell" marker (Chr(13) + Chr(7)) which you need to remove:
Private Sub CompararColumnas_Click()
Dim wrdTbl As Table
'Set your table
With ActiveDocument
If ActiveDocument.Tables.Count > 1 Then
Set wrdTbl = .Tables(InputBox("Table # to copy? There are " & _
.Tables.Count & " tables to choose from."))
Else
Set wrdTbl = .Tables(1) 'default to the only table
End If
End With
Dim AD_UsersPath As String, wb As Object, ws As Object
AD_UsersPath = "C:\Users\" & Environ("Username") & _
"\Desktop\Comparar Columnas VBA\Animales.xlsx"
Dim AD_USERS As Object
Set AD_USERS = CreateObject("Excel.Application")
AD_USERS.Visible = False
Set wb = AD_USERS.Workbooks.Open(AD_UsersPath)
Set ws = wb.Worksheets(1)
Dim LastRow As Long, I As Long, User
LastRow = wrdTbl.Columns(1).Cells.Count
For I = 1 To LastRow
wVal = TwrdTbl.Cell(I, 1)
Left(wVal, Len(wVal)-2) 'strip off "end of cell" marker
User = ws.Cells(ws.Range("A:A").Find(What:=wVal).Row, 1).Text
wrdTbl.Cell(I, 2).Range.Text = User
Next I
wb.Close False
AD_USERS.Quit
End Sub

Related

Search a folder of files for a keyword, copy offset data from the reoccurring keyword to a new workbook

I need to create code that does the following:
Searches a destination folder that contains hundreds of excel sheets
Looks for the string "Current Risk" (the cell containing the string Current Risk is merged&centered - does this count as Column 1?)
Once the keyword is found, copies and pastes data in different columns under the equipment ID that is:
3a) (2,2) from the keyword [this will return the ID from attached picture below]
3b) (5,3) from the keyword [this will return the corrosion rate from the picture]
3c) (5,4) from the keyword [ this will return the remaining half-life from the picture]
There will be other boxes lower down with the same Current Risk target word but with different equipment IDs.
We need to collect all this data again for the next equipment ID for each encounter of the word Current Risk. So loop down the sheet collecting all the current risk data with each encounter and then onto the next workbook in the folder and repeat.
Paste all this data into a new master Workbook.
Code for a previous project that might give a head start. This code looked for keywords at the top of a column and pasted the whole column's data into a new master workbook head-to-tail one after another.
Sub Merges()
Dim strFileName As String
Dim strFilesLike As String
Dim strPathName As String
Dim strCurrentFile As String
pth = "C:\Users\phil\Desktop\Reports\MASTER\"
Set tgt = Workbooks.Open(pth & "master file.xlsx")
strPathName = "C:\Users\phil\Reports\MASTER\Data\"
strFilesLike = "*.xls*"
strFileName = strPathName & strFilesLike
strCurrentFile = Dir(strFileName)
Do While strCurrentFile <> ""
' Combine file data code goes here
Set src = Workbooks.Open(strPathName & strCurrentFile)
Set dest = tgt.Sheets(1).Cells(Rows.Count, 1).End(xlUp).Offset(1)
Set src = ActiveWorkbook
With src.Sheets("Hierarchy Item Attributes")
Set colh = .Range("1:1").Find("Hierarchy Item Site")
cnt = Cells(Rows.Count, colh.Column).End(xlUp).Row - 1
dest.Resize(cnt).Value = colh.Offset(1).Resize(cnt).Value
Set colh = .Range("1:1").Find("Hierarchy Item Address")
dest.Offset(, 1).Resize(cnt).Value = colh.Offset(1).Resize(cnt).Value
On Error Resume Next
Set colh = .Range("1:1").Find("Hierarchy Item Address")
dest.Offset(, 2).Resize(cnt).Value = colh.Offset(1).Resize(cnt).Value
Set colh = .Range("1:1").Find("Hierarchy Item Name")
dest.Offset(, 3).Resize(cnt).Value = colh.Offset(1).Resize(cnt).Value
End With
src.Close False
' Get next file to Import
strCurrentFile = Dir
Loop
End Sub
Picture of one of the xlsm sheets to search
This creates a new Master workbook. Use FindNext to continue the search.
Option Explicit
Sub Merges()
Const PTH = "C:\Users\phil\Desktop\Reports\MASTER\"
Const TERM = "Current Risk"
Dim wbMaster As Workbook, wb As Workbook
Dim ws As Worksheet, wsMaster As Worksheet
Dim strFileName As String, strFilesLike As String
Dim strPathName As String, strCurrentFile As String
Dim strMaster As String
Dim r As Long, n As Long
Dim rng As Range, first As String
Set wbMaster = Workbooks.Add(1)
Set wsMaster = wbMaster.Sheets(1)
With wsMaster
.Name = "Master"
.Range("A1:D1") = Array("ID", "Corrosion Rate", "Half Life", "Sheet")
End With
r = 2
strPathName = PTH & "Data1\"
strFilesLike = "*.xls*"
strFileName = strPathName & strFilesLike
strCurrentFile = Dir(strFileName)
Application.ScreenUpdating = False
Do While strCurrentFile <> ""
Set wb = Workbooks.Open(strPathName & strCurrentFile, True, True)
For Each ws In wb.Sheets
With ws.UsedRange
Set rng = .Find(TERM, lookat:=xlWhole, LookIn:=xlValues, after:=.Cells(.Cells.Count))
If Not rng Is Nothing Then
first = rng.Address
Do
wsMaster.Cells(r, 1) = ws.Cells(rng.Row + 1, "B") 'ID
wsMaster.Cells(r, 2) = ws.Cells(rng.Row + 8, "E") 'Corrision Rate
wsMaster.Cells(r, 3) = ws.Cells(rng.Row + 8, "F") 'Half Life
wsMaster.Cells(r, 4) = wb.Name & " " & ws.Name & " row " & rng.Row
r = r + 1
Set rng = .FindNext(rng)
Loop While rng.Address <> first
End If
End With
Next
wb.Close False
' Get next file to Import
strCurrentFile = Dir
n = n + 1
Loop
Application.ScreenUpdating = True
' save
strMaster = PTH & "master_" & Format(Now(), "yyyy-mm-dd_hhmmss")
wbMaster.SaveAs strMaster
'wbMaster.Close
MsgBox n & " files scanned into " & strMaster, vbInformation
End Sub

Macro help for cutting reports by name

I have the below macro that cuts my report up by name (when it asks me which column to filter on, its 2).
It works perfectly for I need, as it also saves down each cut per person for each report where the report is saved. However, I also need it to pick up everything by name of person in all other tabs in the report. EG: Dave Smith is on the main summary page, and the below macro cuts it by Dave Smith, and saves that cut down. But Dave Smith also has data in 7/8 other tabs, that also need to be included in the new, saved down cut.
Sub parse_data()
'This macro splits data into multiple worksheets
'based on the variables on a column found in Excel.
'An InputBox asks you which columns you'd like
'to filter by, and it just creates these worksheets.
Const TITLE_ROW = 1
Dim wbOut As Workbook
Dim ws As Worksheet, wsOut As Worksheet
Dim iLastRow As Long, iRow As Long
Dim iFilterCol As Integer
Dim sPath As String
' get filter column nu,ber
iFilterCol = Application.InputBox( _
prompt:="Which column would you like to filter by?", _
title:="Filter column", Default:="3", Type:=1)
If iFilterCol < 1 Then
MsgBox iFilterCol & " not valid", vbCritical
Exit Sub
End If
Set ws = ActiveSheet
sPath = ThisWorkbook.Path & "\"
iLastRow = ws.Cells(ws.Rows.Count, iFilterCol).End(xlUp).Row
Dim dict As Object, key
Set dict = CreateObject("Scripting.Dictionary")
' get unique values using dictionary
For iRow = TITLE_ROW + 1 To iLastRow
key = Trim(ws.Cells(iRow, iFilterCol))
If Not dict.exists(key) Then
dict.Add key, iRow
End If
Next
' create separate workbooks
Application.ScreenUpdating = False
For Each key In dict
' apply filter
ws.Rows(TITLE_ROW).AutoFilter Field:=iFilterCol, Criteria1:=key
' create new workbook
Set wbOut = Workbooks.Add
Set wsOut = wbOut.Sheets(1)
wsOut.Name = key
ws.Range("A" & TITLE_ROW & ":A" & iLastRow).EntireRow.Copy wsOut.Range("A1")
wsOut.Columns.AutoFit
' save and close
wbOut.SaveAs (sPath & key & ".xlsx")
wbOut.Close False
Next
ws.Activate
ws.AutoFilterMode = False
Application.ScreenUpdating = True
MsgBox dict.Count & " workbooks created", vbInformation
End Sub
Use Find to locate the filter column for the other sheets, apply filter and repeat the code for the first sheet.
Option Explicit
Sub parse_data()
'This macro splits data into multiple worksheets
'based on the variables on a column found in Excel.
'An InputBox asks you which columns you'd like
'to filter by, and it just creates these worksheets.
Const TITLE_ROW = 1
Dim wbOut As Workbook, wb As Workbook
Dim ws As Worksheet, wsOut As Worksheet, wsOther As Worksheet
Dim rng As Range
Dim iLastRow As Long, iRow As Long, iLastOther As Long
Dim iFilterCol As Integer, n As Integer
Dim sPath As String, sSummary As String
' get filter column nu,ber
iFilterCol = Application.InputBox( _
prompt:="Which column would you like to filter by?", _
Title:="Filter column", Default:="3", Type:=1)
If iFilterCol < 1 Then
MsgBox iFilterCol & " not valid", vbCritical
Exit Sub
End If
Set wb = ThisWorkbook ' or ActiveWorkbook
Set ws = ActiveSheet
sSummary = ws.Name
sPath = ThisWorkbook.Path & "\"
iLastRow = ws.Cells(ws.Rows.Count, iFilterCol).End(xlUp).Row
Dim dict As Object, key
Set dict = CreateObject("Scripting.Dictionary")
' get unique values using dictionary
For iRow = TITLE_ROW + 1 To iLastRow
key = Trim(ws.Cells(iRow, iFilterCol))
If Not dict.exists(key) Then
dict.Add key, iRow
End If
Next
' create separate workbooks
Application.ScreenUpdating = False
For Each key In dict
' apply filter
ws.Rows(TITLE_ROW).AutoFilter Field:=iFilterCol, Criteria1:=key
' create new workbook
Set wbOut = Workbooks.Add(xlWBATWorksheet) ' 1 sheet
Set wsOut = wbOut.Sheets(1)
wsOut.Name = key
ws.Range("A" & TITLE_ROW & ":A" & iLastRow).EntireRow.Copy wsOut.Range("A1")
wsOut.Columns.AutoFit
' search other worksheets
For Each wsOther In wb.Sheets
If wsOther.Name <> sSummary Then
'find name to get filter column
wsOther.AutoFilterMode = False
Set rng = wsOther.UsedRange.Find(CStr(key), LookIn:=xlValues, lookat:=xlWhole)
If Not rng Is Nothing Then
iLastOther = wsOther.Cells(ws.Rows.Count, rng.Column).End(xlUp).Row
wsOther.Rows(TITLE_ROW).AutoFilter _
Field:=rng.Column, Criteria1:=CStr(key)
n = wbOut.Sheets.Count
Set wsOut = wbOut.Sheets.Add(after:=wbOut.Sheets(n))
wsOut.Name = wsOther.Name
wsOther.Range("A" & TITLE_ROW & ":A" & iLastOther).EntireRow.Copy _
wsOut.Range("A1")
wsOut.Columns.AutoFit
End If
wsOther.AutoFilterMode = False
End If
Next
' save and close
wbOut.SaveAs (sPath & key & ".xlsx")
wbOut.Close False
Next
ws.Activate
ws.AutoFilterMode = False
Application.ScreenUpdating = True
MsgBox dict.Count & " workbooks created", vbInformation
End Sub

Filter pivot table (connected to an external source) with range of random items

I have a list of random items that I want to filter in an Excel pivot table. The pivot table is connected to an external data source. Is there any way I can filter my entire list in the pivot table without adding one item at a time to the filter?
I've tried below code in VBA, which works on a local data source, but not when it's external.
"56607016", "84000110", "8A20371" are some examples of items from my list.
If there is a better solution than VBA here, please tell me.
Sub FilterPivotItems()
Dim PT As PivotTable
Dim PTItm As PivotItem
Dim FiterArr() As Variant
' use an array to select the items in the pivot filter you want to keep visible
FiterArr = Array("56607016", "84000110", "8A20371")
' set the Pivot Table
Set PT = ActiveSheet.PivotTables("PivotTable2")
' loop through all Pivot Items in "Product number" Pivot field
For Each PTItm In PT.PivotFields("[Released products].[Product number].[Product number]").PivotItems
If Not IsError(Application.Match(PTItm.Caption, FiterArr, 0)) Then ' check if current item is not in the filter array
PTItm.Visible = True
Else
PTItm.Visible = False
End If
Next PTItm
End Sub
The error message I get when running:
"Run-time error '1004': Unable to get the _NewEnum property of the PivotItems class"
Instead of using For Each loop, change the FilterArr to pivot reference and then you can use set the value of the .VisibleItemsList to your FilterArr. Here is an example.
FilterArr = Array( _
"[myTableName].[myPivotField].&[myPivotItem1]", _
"[myTableName].[myPivotField].&[myPivotItem2]")
ActiveSheet.PivotTables("PivotTable2").PivotFields( _
"[myTableName].[myPivotField].[myPivotField]").VisibleItemsList = FilterArr
This example assumes that you have a worksheet in the same workbook, with a table that contains the values for which the pivot table should be filtered. The pivot filter string for each filter value is created with a formula in the adjacent column and then read into an array. Additional variables are created with the values from named ranges.
Sub FilterPivot_WithListOfValues()
'---------------------------------------------------------------------------------------------------------
' Purpose: Dynamically create an array based on the values of one column of a table.
'
' Customize: Inputs in this sub come from 6 named ranges on a worksheet in this workbook.
' myPivotTableName, myPivotFieldName, mySheetName,
' myFilterTableName, smyDataTableName, myFilterCol
'
' Revisions:
' 09/30/19 Sub created
'
'---------------------------------------------------------------------------------------------------------
'~~~> Set the data types for the variables.
Dim oPT As PivotTable
Dim oPF As PivotField
Dim oPI As PivotItem
Dim strPT As String 'pivot table name
Dim strPF As String 'pivot field name
Dim strWS As String 'pivot table sheet name
Dim oWS As Worksheet
Dim oFTable As ListObject
Dim oDTable As ListObject
Dim strFTable As String 'filter table name
Dim strDTable As String 'data table name
Dim strFilterString As String 'pivot table filter string
Dim FilterArr() As Variant
Dim TempArray
Dim i As Long
Dim iCol As Long
'~~~> Assign the variables.
strPT = [myPivotTableName]
strPF = [myPivotFieldName]
strWS = [mySheetName]
strFTable = [myFilterTableName]
strDTable = [myDataTableName]
iCol = [myFilterCol]
'~~~> Build the filter string. Don't include the quotation marks wrapper.
' That is automatically added by .PivotFields
strFilterString = "[" & strDTable & "].[" & strPF & "].[" & strPF & "]"
'~~~> Check the variables in the Immediate Window.
Debug.Print "Variable Set: strPT = " & strPT
Debug.Print "Variable Set: strPF = " & strPF
Debug.Print "Variable Set: strWS = " & strWS
Debug.Print "Variable Set: strDTable = " & strDTable
Debug.Print "Variable Set: strFTable = " & strFTable
Debug.Print "Variable Set: iCol = " & iCol
Debug.Print "Variable Set: strFilterString = " & strFilterString
'~~~> Set the path for the table variable
Set oFTable = Range(strFTable).ListObject
'~~~> Set the path for the sheet variable
Set oWS = Worksheets(strWS)
'~~~> Create an array list from a table column.
TempArray = oFTable.DataBodyRange.Columns(iCol)
'~~~> Convert from vertical array to horizontal array list.
FilterArr = Application.Transpose(TempArray)
DisplayArrayValues:
'~~~> Loop through each item in the table array and display in Immediate Window [ctrl + g]
For i = LBound(FilterArr) To UBound(FilterArr)
Debug.Print FilterArr(i)
Next i
ApplyPivotFilters:
'~~~> Apply filters to the pivot table.
Set oPF = oWS.PivotTables(strPT).PivotFields(strFilterString)
With oPF
.VisibleItemsList = FilterArr
End With
ReleaseVariables:
'~~~> Release the variables from memory.
Set oPT = Nothing
Set oPF = Nothing
Set oPI = Nothing
Set oWS = Nothing
Set oFTable = Nothing
Set oDTable = Nothing
strPT = vbNullString
strPF = vbNullString
strWS = vbNullString
strFTable = vbNullString
strDTable = vbNullString
strFilterString = vbNullString
i = vbNull
iCol = vbNull
End Sub
This is a snip of the filter table and named ranges.
This is the formula that is used to generate the filter string.
="["&myDataTableName&"].["&myPivotFieldName&"].&["&[#[Pivot Items]]&"]"

Access DB cant return focus to inputbox

I am using an Access Db to export some information to an Excel Workbook. I am using an input form to add dates to the query that creates the sheet. If I create 1 sheet the export works. If I create more than one sheet once the query goes to the second sheet the focus stays on the excel spreadsheet. If you enter a date it goes on cell A1 of the spreadsheet instead of the input box. Any help is appreciated.
Public Function ExportSpreadSheet(path As String)
Dim xlPath As String, I As Integer
Dim DB As Database
Dim myrs As Recordset ' Create a recordset to hold the data
Dim strSQL As String
Dim myExcel As New Excel.Application ' Create Excel with Early binding
Dim wrkbk As Object
Dim wrksht As Object
Dim targetworkbook As Excel.Workbook
Dim FileRange, name As String
Dim extraChar, queryForTransfer, searchSheet As String
Dim objXL As Object
Dim objAC As Object
Dim x As Integer
Dim myFileName As String
Dim sheetDate As String
Dim sheetName As String
Dim amtofsheets As Long
Dim s As Long
Dim ctlCurrentControl As Control
Dim strAnswer As String
On Error GoTo Err_ExportSpreadSheet
DoCmd.SetWarnings False
xlPath = path
amtofsheets = InputBox("Enter amount of sheets", "Amount of Sheets")
Set DB = CurrentDb
Set objAC = CreateObject("Access.application", "")
For s = 1 To amtofsheets
strAnswer = Forms("Browse1").txtFileSelection
sheetDate = InputBox("Enter Trade Date of Entries ex 10/04/2017", "Trade Date")
If s = 1 Then Set objXL = CreateObject("Excel.application", "")
If s = 1 Then objXL.Visible = True
If s = 1 Then objXL.DisplayAlerts = True
If s = 1 Then Set targetworkbook = objXL.Workbooks.Add
'Add worksheet if need more than three worksheets
strSQL = "SELECT FXOpenDeals.city, FXOpenDeals.[As of Date], FXOpenDeals.[Cnt Pty name], FXOpenDeals.[deal number], FXOpenDeals.value, FXOpenDeals.ccy1, FXOpenDeals.[ccy1 amt], FXOpenDeals.ccy2, FXOpenDeals.[ccy2 amt], FXOpenDeals.[unrealized G/L_PV] " _
& " FROM [A1-Internal_Customers] INNER JOIN FXOpenDeals ON [A1-Internal_Customers].[counterparty number] = FXOpenDeals.[counterparty number] " _
& " WHERE FXOpenDeals.[trade] = #" & Format(sheetDate, "mm/dd/yyyy") & "#" _
& " ORDER BY FXOpenDeals.[Cnt Pty name];"
Set myrs = DB.OpenRecordset(strSQL)
If amtofsheets = 1 Or amtofsheets = 2 Then
For I = 1 To targetworkbook.Worksheets.Count
sheetName = "Sheet" & I
Select Case sheetName
Case "Sheet2"
targetworkbook.Sheets("Sheet2").Delete
Case "Sheet3"
targetworkbook.Sheets("Sheet3").Delete
End Select
Next I
End If
If s > 3 Then
With targetworkbook
.Sheets.Add After:=Sheets(Worksheets.Count)
ActiveSheet.name = "Sheet" & s
End With
End If
'Get spreadsheet headers
x = 0
For Each Field In myrs.Fields 'RS being my Recordset variable
targetworkbook.Worksheets("Sheet" & s).Range("A1").Offset(0, x).Value = Field.name
x = x + 1
Next Field
targetworkbook.Worksheets("Sheet" & s).Range("A2").CopyFromRecordset myrs
targetworkbook.Worksheets("Sheet" & s).Columns("A:K").AutoFit
'Name Worksheet
sheetName = Format(sheetDate, "mm-dd")
targetworkbook.Sheets("Sheet" & s).name = sheetName
Next s
DoCmd.SetWarnings False
myFileName = "Internal Customer FX Deals"
targetworkbook.SaveAs FileName:=xlPath & myFileName, FileFormat:=xlWorkbookNormal
targetworkbook.Close SaveChanges:=False
DoCmd.SetWarnings True
If Not objXL Is Nothing Then
objXL.Quit
objXL.DisplayAlerts = True
Set objXL = Nothing
Set myrs = Nothing
End If
MsgBox "Internal Customer FX Deals Data successfully Exported", vbOKOnly
Exit_ExportSpreadSheet:
Exit Function
Err_ExportSpreadSheet:
Err.Clear
Resume Exit_ExportSpreadSheet
End Function
Seems to me that you are doing a whole lot of work for nothing. There's not need to automate Excel unless you want to do some formatting. Simply export the query to Excel via TransferSpreadsheet. Instead of the input box, use a parameter in the query, or better yet, a small form with a textbox.
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, "yourQueryName", "FileName", True, "SheetName"

Split an excel file into multiple workbooks based on the contents of a column

I'm not experienced with VBA, but I think it's the only way for this to work.
I need to send a report to each sales team, but don't want to send them the information of other sales team. There are multiple sheets per workbook with different reports which all have a sales team column.
I would like all the sheets to be filtered by sales team, and create a new workbook for each team.
I appreciate any help.
I got this solution.
Just send me an email if you need this solution.
At first I got this format:
I create the following macro code
Option Explicit
Dim MainWorkBook As Workbook
Dim NewWorkBook As Workbook
Sub ExportWorksheet()
Dim Pointer As Long
Set MainWorkBook = ActiveWorkbook
Range("E2").Value = MainWorkBook.Sheets.Count
Application.ScreenUpdating = False 'enhance the performance
For Pointer = 2 To MainWorkBook.Sheets.Count
Set NewWorkBook = Workbooks.Add
MainWorkBook.Sheets(Pointer).Copy After:=NewWorkBook.Sheets(1)
Application.DisplayAlerts = False
NewWorkBook.Sheets(1).Delete
Application.DisplayAlerts = True
With NewWorkBook
.SaveAs Filename:="C:\Users\lengkgan\Desktop\Testing\" & MainWorkBook.Sheets(Pointer).Name & ".xls" 'you may change to yours
End With
NewWorkBook.Close SaveChanges:=True
Next Pointer
Application.ScreenUpdating = True
Range("D5").Value = "Export Completed"
End Sub
Following is the output
I have written a VBA(Macro) program which will work based on Input data. All you need to do is, provide input data in a column in another sheet. Macro will read the data and filter Master Sheet based on each row then it Generate new excel sheet based on find data.
enter Option Explicit
Dim personRows As Range 'Stores all of the rows found
'Split data into separate columns baed on the names defined in
'a RepList on the 'Names' sheet.
Sub SplitSalesData()
Dim wb As Workbook
Dim p As Range
Dim counter2 As Integer
Dim i As Integer
counter2 = 0
i = 0
Application.ScreenUpdating = False
' in my case i am generating new excel based on every 8 reacords from begining. You can simplyfy this logic based on your need.
For Each p In Sheets("Names").Range("RepList") ' Give the name of your input sheet and column
If i = 0 Then ' We are starting, so generate new excel in memeory.
Workbooks.Add
Set wb = ActiveWorkbook
ThisWorkbook.Activate
End If
WritePersonToWorkbook wb, p.Value
i = i + 1 ' Increment the counter reach time
If i = 8 Then ' As my need is after processing every 8 uniqe record just save the excel sheet and reset the processing
counter2 = counter2 + 1
wb.SaveAs ThisWorkbook.Path & "\salesdata_" & CStr(counter2) ' save the data at current directory location.
wb.Close
Set personRows = Nothing ' Once the process has completed for curent excelsheet, set the personRows as NULL
i = 0
End If
Next p
Application.ScreenUpdating = True
Set wb = Nothing
End Sub
'Writes all the data rows belonging to a RepList
Sub WritePersonToWorkbook(ByVal SalesWB As Workbook, _
ByVal Person As String)
Dim rw As Range
Dim firstRW As Range
For Each rw In UsedRange.Rows
If Not Not firstRW Is Nothing And Not IsNull(rw) Then
Set firstRW = rw ' WE want to add first row in each excel sheet.
End If
If Person = rw.Cells(1, 5) Then ' My filter is working based on "FeederID"
If personRows Is Nothing Then
Set personRows = firstRW
Set personRows = Union(personRows, rw)
Else
Set personRows = Union(personRows, rw)
End If
End If
Next rw
personRows.Copy SalesWB.Sheets(1).Cells(1, 1) ' Adding data in Excel sheet.
End Sub
please find below code
Sub SplitSheetDataIntoMultipleWorkbooksBasedOnSpecificColumn()
Dim objWorksheet As Excel.Worksheet
Dim nLastRow, nRow, nNextRow As Integer
Dim strColumnValue As String
Dim objDictionary As Object
Dim varColumnValues As Variant
Dim varColumnValue As Variant
Dim objExcelWorkbook As Excel.Workbook
Dim objSheet As Excel.Worksheet
Dim icol As Long
Dim l As Long
Dim headercol As Long
Dim stroutputfolder As String
stroutputfolder = "D:\Ba"
'dim str
icol = 1
headercol = 3
Set objWorksheet = ActiveSheet
nLastRow = objWorksheet.Range("A" & objWorksheet.Rows.Count).End(xlUp).Row
Set objDictionary = CreateObject("Scripting.Dictionary")
For nRow = headercol + 1 To nLastRow
'Get the specific Column
'Here my instance is "B" column
'You can change it to your case
strColumnValue = objWorksheet.Cells(nRow, icol).Value
If objDictionary.Exists(strColumnValue) = False Then
objDictionary.Add strColumnValue, 1
End If
Next
varColumnValues = objDictionary.Keys
For i = LBound(varColumnValues) To UBound(varColumnValues)
varColumnValue = varColumnValues(i)
'MsgBox (varColumnValues(i))
If Dir(stroutputfolder, vbDirectory) = vbNullString Then MkDir stroutputfolder
If CStr(varColumnValue) <> "" Then
objWorksheet.UsedRange.Offset(headercol - 1, 0).AutoFilter Field:=icol, Criteria1:=CStr(varColumnValue)
Set objExcelWorkbook = Excel.Application.Workbooks.Add
Set objSheet = objExcelWorkbook.Sheets(1)
objSheet.Name = objWorksheet.Name
objWorksheet.UsedRange.SpecialCells(xlCellTypeVisible).Copy Destination:=[A1]
'strFilename = strOutputFolder & "\" & strItem
ActiveWorkbook.SaveAs Filename:=stroutputfolder & "\" & CStr(varColumnValue) & ".xlsb", FileFormat:=50
ActiveWorkbook.Close savechanges:=False
l = l + 1
End If
Next
objWorksheet.ShowAllData
MsgBox (l & " files splitted")
End Sub

Resources