Partial string match then return value - vba

I'm working on a way to quickly code bank transactions. I have one tab of bank data downloaded (sheet 1) and I want to search the descriptions (column B) for a partial match with sheet 2, column A. Then if match found, return the value from sheet 2, column B to sheet 1 column D; and sheet 2, column C to sheet 1, column E.
Sheet 1
Column A Column B Column C Column D Column E
11/1/17 Transfer from Account 60617829-D 276 {acct} {location}
11/1/17 Transfer from Account 60692022-D 551.46 {acct} {location}
Sheet 2
Column A Column B (acct) Column C (location)
60617829-D 10430 03
60692022-D 10490 09
I was trying to use a solution similar to "Find and Get" described here: Excel Formula/VBA to search partial strings in other sheet
However, the following code returns the first value from sheet 2 to all values on sheet 1 without properly matching them. I think my error is in how I'm trying to use an array when it may not be necessary but I am at a loss.
Sub findAndGet()
Dim sh1, sh2 As Worksheet
Dim tempRow1, tempRow2 As Integer
Dim strList() As String
Dim name As String
Dim index As Integer
'Set sheets
Set sh1 = Sheets("list")
Set sh2 = Sheets("search")
'Set the start row of Sheet1
tempRow1 = 1
'Loop all row from starRow until blank of column A in Sheet1
Do While sh1.Range("A" & tempRow1) <> ""
'Get name
name = sh1.Range("B" & tempRow1)
'Split by space
strList = Split(Trim(name), " ")
'Set the start row of Sheet2
tempRow2 = 1
'Reset flag
isFound = False
'Loop all row from startRow until blank of column A in Sheet2
Do While sh2.Range("A" & tempRow2) <> ""
For index = LBound(strList) To UBound(strList)
'If part of name is found.
If InStr(UCase(sh2.Range("A" & tempRow2)), UCase(strList(index))) > 0 Then
'Set true to search flag
isFound = True
'exit do loop
Exit Do
End If
Next index
'Increase row
tempRow2 = tempRow2 + 1
Loop
'If record is found, set output
If isFound Then
'set account
sh1.Range("D" & tempRow1) = sh2.Range("B" & tempRow2)
'set location
sh1.Range("E" & tempRow1) = sh2.Range("C" & tempRow2)
End If
'Increase row
tempRow1 = tempRow1 + 1
Loop
End Sub

If formula solution is acceptable then assuming that data begins on both sheets on row number 2.
In cell D2 of Sheet1 insert following formula and copy down.
=LOOKUP(2^15,SEARCH(Sheet2!$A$2:$A$3,Sheet1!B2,1),Sheet2!$B$2:$B$3)
In cell E2 of Sheet1 insert following formula and copy down.
=LOOKUP(2^15,SEARCH(Sheet2!$A$2:$A$3,Sheet1!B2,1),Sheet2!$C$2:$C$3)

Related

VBA Split Cells and paste only specific cells

updated*
im new to VBA so help would be appreciated
i have a sheet where i have in column A content in this structure:
A1: Columnheader
A2: 044000 randomwordx (3 spaces between number and randomwords)
A3: 056789 randomwordy (3 spaces between number and randomwords)
A4:
A5: a.) randomwords
A6: 3.randomwords
A7:
A8: 600000 randomwordz (3 spaces between number and randomwords)
A9: 654124 randomwords (3 spaces between number and randomwords)
the delimiter between numbers and randomwords in column A is always 3x spaces
what i want to do is the following:
Go to Column A - select all cells which start with a 6-figures number
split these cells and paste them into column C and D
column C should contain only the starting number, remove any leading zeroes (if cell A2 has for example 044000, cell C2 should be 44000)
column D should only contain the text which comes after the starting number of column A (in this example D2 should be "randomwordx"
cells in column A which are blank or dont start with a 6 figure number should NOT be pasted in column C and D (in this example A4,A5,A6,A7 should NOT be pasted into C and D column)
So it should look like this
Column C:
C1: Columnheader
C2:44000
C3:56789
C4:60000
C5:653124
Column D:
D1: Columnheader
D2:randomwordx
D3:randomwordy
D4:randomwordz
D5:randomwords
I managed only to get this far, so help would be appreciated
Option Explicit
Sub Splitcolumn()
Dim mrg As Range
Dim LastRow As Long
Dim r As Range
Dim splitted() As String
With Sheets("test")
Set mrg = Sheets("test").Range("A4:A" & LastRow)
For Each r In mrg
splitted = Split(r.Value, " ")
r.Value = splitted(0)
r.Offset(2, 3).Value = splitted(1) & " " & splitted(2)
Next r
End With
End Sub
i received runtime error 1004
thanks for your help
This should do what you want it to. I used Portland Runner's answer to this post to set up the RegEx reference in my VBA and learn the syntax for it. Instead of a for each loop, I calculate the last row of column A and use a for loop with that many iterations. The i variable is set to 2 to skip the header in row 1.
Sub SplitCol()
'Set references to active workbook and sheet
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ActiveWorkbook
Set ws = wb.ActiveSheet
'Create Regular Expression object and set up options
Dim regEx As New RegExp
With regEx
.Global = True
.MultiLine = True
.IgnoreCase = False
'[0-9] means that regex will check for all digits
'{6} means that a minimum of 6 consecutive chars must meet the [0-9] criteria
.pattern = "[0-9]{6}"
End With
'All .Methods and .Properties will belong to ws object due to With
With ws
'Determine how many rows to loop through
Dim lastRowA As Long
lastRowA = .Range("A" & .Rows.Count).End(xlUp).Row
'Main loop
Dim i As Integer
For i = 2 To lastRowA
'Make sure there is a value in the cell or code will error out
If Cells(i, 1).Value <> "" Then
'Test regex of cell
If regEx.Test(Split(Cells(i, 1).Value, " ")(0)) Then
'If regex was true, set 3rd column (C) equal to numbers and
'4th column (D) equal everything else
Cells(i, 3).Value = Split(Cells(i, 1).Value, " ")(0)
Cells(i, 4).Value = Split(Cells(i, 1).Value, " ")(1)
End If
End If
Next
End With
'Release regEx object to reduce memory usage
Set regEx = Nothing
End Sub
This is what the code should make the sheet look like.

check for duplicates in diffrent worksheets and thereafter print value

I have searched but i cant seem to figure out how to print specified value in the column next to where i find my duplicate. What i have since earlier are code that first specify the diffrent ranges and thereafter look if a duplicate is found in sheet Y from sheet X. Sheet Le is this weeks information and sheet Be is the last weeks information.
IF i find a duplicate in the specified range i want to on my Delivery sheet print in column A next to the duplicate either Delivered or not delivered depending on if my output from function compareAEO print true or false.
The conditions that i am looking for are that if the we can find the same value that are in column B in sheet (Le) on sheet (Be) it will then check if the text in column F has changed. IF SO then it shall print in column A on sheet (Le) = Delivered. Otherwise not delivered.
It then checks to se if the dates in column M is the same. IF not then it shall print Replanned in column A on sheet (Le).
Shortly
IF value in cell on column B, Sheet (Le) = Value in column B, Sheet (Be) then
value in column A on sheet Le = "Delivered" Else "not deliverd".
Then
If value in cell in column M, Sheet (Le) <> If value in cell in column M, Sheet (Be) then value in column A, Sheet(Le) = "replanned"
This is how my data looks like,
Sheet (Le)
Col B Col F Col M
PZ2408 X13 2017-02-13
PZ2345 X30 2017-02-23
PZ2463 X45 2017-02-25
PZ2513 X13 2017-02-10
PZ2533 X70 2017-02-05
PZ2561 X60 2017-02-20
For sheet (Be) my data looks like this
Col B Col F Col M
PZ2408 X30 2017-02-13
PZ2345 X30 2017-02-23
PZ2463 X30 2017-02-25
PZ2513 X13 2017-02-05
PZ2533 X13 2017-02-10
PZ2561 X60 2017-02-17
After the code has done its course i would like it to show for example,
Sheet (Le)
col A Col B Col F Col M
Delivered PZ2408 X13 2017-02-13
Not Delivered PZ2345 X30 2017-02-23
Delivered PZ2463 X45 2017-02-25
replanned PZ2513 X13 2017-02-10
Delivered PZ2533 X70 2017-02-05
replanned PZ2561 X60 2017-02-20
Bascilly my Not delivered, delivered and Replanned statements does not work and my brain does not work.
Can SO help save my day?
Sub checkASMT()
Dim rng1 As Range
Dim rng2 As Range
Dim lastRowSource As Long
Dim lastRowTarget As Long
Dim row As Long
Dim ASMT As String
'Looping trough Range
With ThisWorkbook.Worksheets("Le")
lastRowTarget = .Range("B" & .Rows.Count).End(xlUp).row
For i = 29 To lastRowTarget
ASMT = .Range("b" & i).value
'Define range and see if we can find duplicates
With ThisWorkbook.Worksheets("Be")
lastRowSource = .Range("B" & .Rows.Count).End(xlUp).row
Set rng1 = .Range("B3", "B" & lastRowSource)
row = findValueInRangeReturnRow(rng1, ASMT)
'Check FAX
If compareAEO(i, row, "FAX") = True Then
'Debug.Print compareASMT(i, row, "FAX")
Worksheets("Le").Cells(i, ASMT).value = "Not Delivered"
Else
.Worksheets("Le").Cells(i, ASMT).value = "delivered"
'Check if dax are correct
If compareAEO(i, row, "DAX") = False Then
.Worksheets("Le").ASMT.Offset(0, 1).value = "Replan"
End If
End With
Next i
End With
End Sub
here are my first function
Function findValueInRangeReturnRow(rng As Range, value As Variant) As Long
Set c = rng.Find(value, LookIn:=xlValues)
If Not c Is Nothing Then
findValueInRangeReturnRow = c.row
End If
End Function
My second function that checks if duplicates are found in specified ranges.
Function compareAEO(rad1 As Variant, rad2 As Variant, typeCOMPARE As String) As Boolean
Dim col1 As String
Dim col2 As String
Select Case typeCOMPARE
Case "FAX"
col1 = "F"
col2 = "F"
Case "DAX"
col1 = "M"
col2 = "M"
End Select
If ThisWorkbook.Worksheets("Le").Range(col1 & rad1).value = ThisWorkbook.Worksheets("Be").Range(col2 & rad2).value Then
compareAEO = True
Else
compareAEO = False
End If
End Function
You were getting the last row of both pages in each loop. It is only necessary to get them once at the top, outside the loop. Same for the range you were setting. You can see that I put them at the top, before the loop.
I don't really know what you were using ASMT for. It looks like you were trying to use it as a range in some of your coding instead of range("B" & I). I used strings in the "B" column of Le to compare to the "B" column of Be when I tested it.
It works for me. You'll have to change it to suit your needs. You don't need all the functions, what they accomplished are all within this subroutine.
Sub checkASMT()
Dim rng1 As Range
Dim rng2 As Range
Dim lastRowLE As Long
Dim lastRowBe As Long
Dim row As Long
Dim ASMT As String
Dim LEws As Worksheet
Dim tmpRng As Range
Set LEws = Worksheets("Le")
lastRowLE = Sheets("Le").Cells(ActiveSheet.Rows.Count, "B").End(xlUp).row
lastRowBe = Sheets("Be").Cells(ActiveSheet.Rows.Count, "B").End(xlUp).row
Set rng1 = Sheets("Be").Range("B3", "B" & lastRowBe)
For i = 29 To lastRowLE
Set tmpRng = Sheets("Le").Range("b" & i)
ASMT = tmpRng.Value
Set c = rng1.Find(ASMT, LookIn:=xlValues)
If Not c Is Nothing Then
row = c.row
If ThisWorkbook.Worksheets("Le").Range("F" & i).Value = ThisWorkbook.Worksheets("Be").Range("F" & row).Value Then
' Worksheets("Le").Cells(i, ASMT).Value = "Not Delivered"
' Did you intend to use ASMT as the column number?
' I'm going to hard code that as column 27 for my purposes. You can change it if you need to
LEws.Cells(i, 27).Value = "Not Delivered" ' column 27 is "AA"
Else
LEws.Cells(i, 27).Value = "Delivered"
End If
If ThisWorkbook.Worksheets("Le").Range("M" & i).Value = ThisWorkbook.Worksheets("Be").Range("M" & row).Value Then
' .Worksheets("Le").ASMT.Offset(0, 1).Value = "Replan"
' again I don't understand the reference to ASMT. That is a string value - unless it is a numeric value in the string
' I'm going to assume that you intended for "Replan" to go into column C on row i
Else
LEws.Range("C" & i).Value = "Replan"
End If
End If
Next i
End Sub
Try this; place data in single sheet from B to G (Le then Be); place this formula in column H
=IF(VLOOKUP(E2,B$2:D$7,2,FALSE)=F2,IF(G2<D2,"replanned","Not Delivered"),"delivered")
tweak this formula to suit your needs to make it work across sheets

Compare and Match 2 Columns and Copy the values of Matched items from next Column in Workbook 1 to Empty Column in Workbook 2 against Matched items

I am new to VBA Excel.
Note:
I have written this program for 2 separate sheets but I have originally 2 separate workbooks and I want code to be written for 2 separate workbooks.
Question:
In Workbooks 1, Sheet name (AM_quote-overview_sales-inputs) I have 2 columns. Column A contains Topic Information and In Column B I have the data related to the information.
In Workbook 2 I have Column A containing the Topic Information words some are similar to what I have in AM_quote-overview_sales-inputs Sheet and some are not and in Column B. I need values to be copied from Column B of Workbook 1 sheet (AM_quote-overview_sales-inputs) on matching.
I want a macro in Workbook 2 (Sheet 1) that compares the values of Topic Information present in Column A with Topic Information Present in Column A of Workbook 1 Sheet (AM_quote-overview_sales-inputs) and then copies the values from Column B of workbook 1 sheet (AM_quote-overview_sales-inputs) to Column B of workbook 2 (Sheet 1) .
My written code compares the words but when I add new row in Sheet 1 of Workbook 2 the values that are copied from Column B of Workbook 1 to workbook 2 Column B are not accurate.
I need to compare 2 columns and copies the values of Column B of Workbook 1 Sheet (AM_quote-overview_sales-inputs) to Column B of Workbook 2 (Sheet1) for the compared or matched words from Column A of both sheets.
Have a look at the figures below for detailed information.
Code:
Private Sub CommandButton1_Click()
Dim oldRow As Integer
Dim newRow As Integer
Dim i As Integer
i = 1
For oldRow = 1 To 1170
For newRow = 1 To 1170
If StrComp((Worksheets("AM_quote-overview_sales-inputs").Cells(oldRow, 1).Text), (Worksheets("Sheet1").Cells(newRow, 1).Text), vbTextCompare) <> 0 Then
i = oldRow
Worksheets("Sheet1").Cells(i, 2) = " "
Else
Worksheets("Sheet1").Cells(i, 2) = Worksheets("AM_quote-overview_sales-inputs").Cells(newRow, 2)
i = i + 1
Exit For
End If
Next newRow
Next oldRow
End Sub
1 WorkBook 1 Sheet (AM_quote-overview_sales-inputs) Data
2 Workbook 2 (Sheet 1) Data
Example :
Workbook 1 Sheet AQR Data WorkBook 2 Sheet 1
Col A Col B Col A Col B
Ford 3 BMW
BMW 4 Ford
Jaguar 5 Rolls Royce
Rolls Royce 6 Jaguar
I have 2 Columns in workbooks.
I need a macro in Workbook 2 Sheet 1 that will pick up the values likes BMW etc from Column A and match these values present in Column A of Workbook 1 Sheet AQR and the words which gets matched it copies the values of words like 3, 4 from Column B of Workbook 1 to Column B of Workbook 2 in front of Words.
In front of BMW I need Value like 4 so after matching words I need 4 in Col B of Workbook 2.
If no value is matched or new row is added in Workbook 2 which do not contain some word or value so it should be left empty and I need the values of matched words to be copied in front of respective words.
Please have a look at the line:
Worksheets("Sheet1").Cells(i, 2) = Worksheets("AM_quote-overview_sales-inputs").Cells(newRow, 2)
newRow variable is assigned to output, not to input loop - you should replace it with oldRow and it should work properly then.
You should also reverse the order of loops usage - you should use following logic (please see my Solution 1 example):
For newRow = 1 To 1170
For oldRow = 1 To 1170
...
Next oldRow
Next newRow
As if you find the result for particular value it may be replaced with " " in the next loop.
I have 3 additional remarks which don't affect the result but may impact efficiency:
You can also skip i variable as you can manage everything through variables used in loops.
You don't have to put output cell to " " everytime - with reversed order of loop you can do it before inner loop (I will show it in my example below).
Instead of putting fix max row in the loop, you can search for it - please refer to my example below, where I identify the value for lrow_Input and lrow_Output instead of using '1170'.
Please see below two examples of solution of matching from one Workbook to another:
Assumptions to both solutions:
WB_Input.xlsb is the file where you have 'AM_quote-overview_sales-inputs' worksheet and you want to match values from this WB (structure is as in your example - col A and col B to be used)
WB_Output.xlsb is the file where you want to have the results in col B for values in col A:
I don't know where you want to put your code (in Input or Output file that's why I put exact names of files - once you decide you can replace line assigning workbook to object (for example Set WB_Input = Workbooks("WB_Input.xlsb")) to assign it to ThisWorkbook.
Solution 1 is Your adjusted code:
Sub solution1()
Dim oldRow As Integer
Dim newRow As Integer
Dim lrow_input As Integer, lrow_output As Integer 'variables indicating last fulfilled rows
Dim WB_Input As Workbook
Dim WB_Output As Workbook
Dim WS_Input As Worksheet
Dim WS_Output As Worksheet
Set WB_Input = Workbooks("WB_Input.xlsb")
Set WB_Output = Workbooks("WB_Output.xlsb")
Set WS_Input = WB_Input.Worksheets("AM_quote-overview_sales-inputs")
Set WS_Output = WB_Output.Worksheets("Sheet1")
With WS_Input
lrow_input = .Cells(.Rows.Count, 1).End(xlUp).Row
End With
With WS_Output
lrow_output = .Cells(.Rows.Count, 1).End(xlUp).Row
End With
For newRow = 1 To lrow_output
WS_Output.Cells(newRow, 2).Value = "" 'you clear cell only once, not during each search
For oldRow = 1 To lrow_input
If (StrComp((WS_Input.Cells(oldRow, 1).Value2), (WS_Output.Cells(newRow, 1).Value2), vbTextCompare) = 0) Then
WS_Output.Cells(newRow, 2).Value = WS_Input.Cells(oldRow, 2).Value
Exit For
End If
Next oldRow
Next newRow
End Sub
Solution 2 uses Excel formulas VLOOKUP and IFERROR in the way that code is putting formula to the first cell and copies it to all below (till last needed row). Then calculates it - in case auto calculations are disabled - and pastes results as values:
Sub solution2()
Dim oldRow As Integer
Dim newRow As Integer
Dim lrow_output As Integer 'variable indicating last fulfilled row
Dim WB_Input As Workbook
Dim WB_Output As Workbook
Dim WS_Input As Worksheet
Dim WS_Output As Worksheet
Dim funcStr As String
Set WB_Input = Workbooks("WB_Input.xlsb")
Set WB_Output = Workbooks("WB_Output.xlsb")
Set WS_Input = WB_Input.Worksheets("AM_quote-overview_sales-inputs")
Set WS_Output = WB_Output.Worksheets("Sheet1")
With WS_Output
lrow_output = .Cells(.Rows.Count, 1).End(xlUp).Row
End With
With WS_Input
funcStr = "=IFERROR(VLOOKUP(" & Cells(1, 1).Address(False, False) & "," & "'[" & WB_Input.Name & "]" & .Name & "'!" & Range(.Columns(1), .Columns(2)).Address & ",2,0),"""")"
End With
With WS_Output
.Cells(1, 2).Formula = funcStr
.Cells(1, 2).Copy
Range(.Cells(1, 2), .Cells(lrow_output, 2)).PasteSpecial xlPasteFormulas
WS_Output.Calculate
Range(.Cells(1, 2), .Cells(lrow_output, 2)).Copy
Range(.Cells(1, 2), .Cells(lrow_output, 2)).PasteSpecial xlPasteValues
Application.CutCopyMode = False
End With
End Sub
Please let me know if I understood your problem properly and provided correct solution - if not, please let me know which assumptions are wrong so I adjust it.

Search for same values in sheet1 and sheet2 and copy the values from sheet1 to sheet2

I have worked along time with excel but aren't very good at VBA, so I need help to make an macro and I cant get a recording macro to work :(
I have an excel file with 2 sheets (Sheet1 and Sheet2).
I want to compare a text from Sheet2 (column A) with sheet1 (column B) and if it finds same text in both sheets so do I want the macro to copy column A,B,C and D from sheet1 over to column B,C,D and E in sheet2.
In sheet 1 I have more than 6000 rows so I don't want to do this manually or do a formula in excel, I want a macro that does this for me.
The sheets have headers, can someone maybe help me with this ?
I'm a little unclear on what you are trying to do. This is my interpretation: suppose that, for a value in row X column A on sheet 1 -- if you find a corresponding value on sheet 2 in row Y column B -- you want to copy from sheet 1 the cells on row X belonging to columns A B C D and paste them on sheet 2 in row Y columns B C D E.
If that is correct, try this:
Sub copyCells()
Dim wb As Workbook, firstWs As Worksheet, secondWs As Worksheet
Dim matchIndex As Integer
Set wb = ThisWorkbook
Set firstWs = wb.Worksheets(1)
Set secondWs = wb.Worksheets(2)
Application.ScreenUpdating = False
' We'll start at i=2 to account for the header
For i = 2 To firstWs.Range("A2:A6000").Rows.count
On Error Resume Next
' MATCH will find the row number in sheet 2 - change the range specifications as needed
matchIndex = Application.WorksheetFunction.Match(firstWs.Range("A" & i), secondWs.Range("B2:B6000"), 0)
Err.Clear
On Error GoTo 0
' MATCH will throw an error if it finds no results.
' Hence: if matchindex contains an error, do nothing.
' But if it doesn't contain an error, it must contain a row number - so we can proceed.
If Not Application.WorksheetFunction.IsNA(matchIndex) Then
secondWs.Range("B" & matchIndex).Value = firstWs.Range("A" & i).Value
secondWs.Range("C" & matchIndex).Value = firstWs.Range("B" & i).Value
secondWs.Range("D" & matchIndex).Value = firstWs.Range("C" & i).Value
secondWs.Range("E" & matchIndex).Value = firstWs.Range("D" & i).Value
End If
Next i
Application.ScreenUpdating = True
End Sub

Copying multiple cells in same row based on multiple criteria

Background: I have an Excel file used for tracking credit card payables. There are 18 columns of data (A through R). Out of these 18 columns, I want to use a macro to filter for specific statement date and then for a specific company code.
Each company code will be assigned a new worksheet. In each of these worksheets, I want to bring over specific cells from the master worksheet based on the criteria. For instance, the macro should first sort for statement date (7/31/2012) and then company code (ABC). Then, I need to run a loop to bring over details. For instance, in the master worksheet, the GL code in column P needs to be copied to the "ABC" worksheet in column H.
Here's a summary of what needs to happen:
1. Clear any filters in filter range (A2:R2)
2. Filter for date in cell A1 on "Master" worksheet beginning in cell A3 (date column)
3. Filter for company code (ABC) in column O
That should give a data set for particular company's statement activity. Here's what needs to happen next:
4. Copy Column P cell values in "master" worksheet to Column C in "ABC" worksheet
5. Copy Column N cell values in "master" worksheet to Column D in "ABC" worksheet
6. Copy Column R cell values in "master" worksheet to Column H in "ABC" worksheet
7. Copy Column F cell values in "master" worksheet to Column G in "ABC" worksheet, but max of 30 characters
8. If Column G value in "master" worksheet is >=0, then copy that value to Column E in "ABC" worksheet (otherwise needs to be zero)
9. If column G value in "master" worksheet is <0, then copy that value to Column F in "ABC" worksheet (otherwise needs to be zero)
Is this possible?
Here's a sub that should get you started. I did not implement all your steps, but I believe this is enough to take and finish on your own. If you find this answer is helpful to get you where you need to go, please accept this answer. If you have problems with anything here, please add a comment to this answer asking for clarification.
I have only tested on dummy data, but what I did work with was successful.
Option Explicit
Sub TransferData()
Dim Master As Worksheet
Dim NewSheet As Worksheet
Dim CompanyList As Object
Dim lRow As Long, lMaxRow As Long, lNewRow As Long
Dim vDictItem As Variant
Set CompanyList = CreateObject("Scripting.Dictionary")
Set Master = ThisWorkbook.Sheets("Master")
If Master.FilterMode Then
Master.ShowAllData
End If
Master.Range("A:R").Sort Master.Range("A2"), xlAscending, Master.Range("O2"), , xlAscending, , , xlYes
lMaxRow = Master.Range("A" & Master.Rows.Count).End(xlUp).Row
For lRow = 3 To lMaxRow
If Not CompanyList.Exists(Master.Range("A" & lRow).Value) Then
CompanyList.Add Master.Range("A" & lRow).Value, Master.Range("A" & lRow).Value
End If
Next lRow
For Each vDictItem In CompanyList.Keys
Master.Range("A3:R" & lMaxRow).AutoFilter 1, vDictItem
If Master.Cells.SpecialCells(xlCellTypeVisible).Count > 0 Then
Set NewSheet = ThisWorkbook.Worksheets.Add
NewSheet.Name = vDictItem
lNewRow = 1
For lRow = 3 To lMaxRow
If Master.Rows(lRow).Hidden = False Then
lNewRow = lNewRow + 1
NewSheet.Range("C1").Value = Master.Range("P1").Value
NewSheet.Range("C" & lNewRow).Value = Master.Range("P" & lRow).Value
NewSheet.Range("G1").Value = Master.Range("F1").Value
NewSheet.Range("G" & lNewRow).Value = Left(Master.Range("F" & lRow).Value, 30)
NewSheet.Range("E1").Value = Master.Range("G1").Value & " (POS)"
NewSheet.Range("F1").Value = Master.Range("G1").Value & " (NEG)"
If Master.Range("G" & lRow).Value >= 0 Then
NewSheet.Range("E" & lNewRow).Value = Left(Master.Range("G" & lRow).Value, 30)
Else
NewSheet.Range("F" & lNewRow).Value = Left(Master.Range("G" & lRow).Value, 30)
End If
End If
Next lRow
End If
Next vDictItem
End Sub