1

I have this code so far, only does it for sheet 2, how can I alter this code to include multiple sheets into this? Complete newb here. :

Sub extractuniquevalues()

    Sheet1.Range("C:C").AdvancedFilter xlFilterCopy, , Sheet4.Range("C1"), True
    Sheet2.Range("C:C").AdvancedFilter xlFilterCopy, , Sheet4.Range("C1"), True

End Sub
mielk
  • 3,890
  • 12
  • 19
Jonathan
  • 313
  • 4
  • 16
  • If you mean you want a unique list from several sheets, you have to copy the data to one sheet, then use advanced filter on that combined data set. – Rory Jul 27 '15 at 14:03
  • Oh, so I can't do it across multiple worksheets? Do I hav eto copy the data into the one sheet? – Jonathan Jul 27 '15 at 14:35
  • Yes, if you want to use Advanced Filter. You can minimise the data by only copying the unique data from each sheet, then filtering that result set for a final unique list. – Rory Jul 27 '15 at 14:41

2 Answers2

4

You can do it like that:

Filter data in place:

Sub extractuniquevalues()
    Dim wks As Excel.Worksheet

    For Each wks In Excel.ActiveWorkbook.Worksheets
        Call wks.Range("C:C").AdvancedFilter(XlFilterAction.xlFilterInPlace, , , True)
    Next wks

End Sub

Filter data and paste them into a new worksheet:

Sub extractuniquevalues2()
    Dim wks As Excel.Worksheet
    Dim wksSummary As Excel.Worksheet
    '----------------------------------------------------------------------------------

    On Error Resume Next
    Set wksSummary = Excel.ThisWorkbook.Worksheets("Unique data")
    On Error GoTo 0

    If wksSummary Is Nothing Then
        Set wksSummary = Excel.ThisWorkbook.Worksheets.Add
        wksSummary.Name = "Unique data"
    End If


    'Iterate through all the worksheets, but skip [Summary] worksheet.
    For Each wks In Excel.ActiveWorkbook.Worksheets

        With wksSummary

            If wks.Name <> .Name Then
                If Application.WorksheetFunction.CountA(wks.Range("C:C")) Then
                    Call wks.Range("C:C").AdvancedFilter(xlFilterCopy, , .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row + 1, 1), True)
                End If
            End If

        End With

    Next wks

End Sub

Unique data from each worksheet are printed in the first column of a new worksheet called Unique data.

This method filters data from each worksheet separately, so if there is for example value A in Sheet1 and value A in Sheet2, there will be two entries A in the result list.


Note that first value is considered to be a header and it can be duplicated in the result list.

mielk
  • 3,890
  • 12
  • 19
  • If you are totally new to vba then it is also worth mentioning `ThisWorkbook`. `ActiveWorkbook` is the `Workbook` object that is automatically updated to reference the workbook that you are actively working on. `ThisWorkbook` is the `Workbook` object that references the workbook that the running code is contained in. If you or your user may work with multiple books at once this difference is important. – Michael S Priz Jul 27 '15 at 14:12
  • You're just going to end up with the _last_ worksheet's unique values in `Sheet4`, column `C`, however. – Bond Jul 27 '15 at 14:18
  • I was planning on doing this macro across multiple sheets and workbooks in a directory. Anyway running the macro above I just get the header in sheet4, maybe im doing something wrong. – Jonathan Jul 27 '15 at 14:36
  • @Jonathan You are right, all the filters printed their values in worksheet Sheet4. I have already edited the code in answer - it should print filtered data in each worksheet. – mielk Jul 27 '15 at 14:42
  • @mielk,Works fine, thanks :) , anyway I can extract these to a master sheet? Or to a 4th sheet? – Jonathan Jul 27 '15 at 14:56
  • @mielk, I get an error ` wksSummary.Name = "Unique data"`, cannot rename sheet to another sheet. I tried changing unique data to data. – Jonathan Jul 27 '15 at 15:34
  • @Jonathan This error means that you have already a worksheet called 'Unique data'. I have modified the code that way that it first looks for the worksheet 'Unique data' and if this worksheet is not found, it is created from scratch. – mielk Jul 27 '15 at 16:27
  • @mielk, Hi mielk, the code is the same as before, did you forget to upload ? I do not have a worksheet named Unique Data..hmm – Jonathan Jul 27 '15 at 17:15
  • @MichaelSPriz , Hi Michael, The users will most likely using multple workbooks at once, what does this mean? – Jonathan Jul 27 '15 at 17:17
  • @Jonathan If you only want this macro to affect the workbook it is contained in then you should use `ThisWorkbook` instead of `ActiveWorkbook`. Refer to [this](https://msdn.microsoft.com/en-us/library/bb221809(v=office.12).aspx) for documentation on `ThisWorkbook`. Refer to [this](https://msdn.microsoft.com/en-us/library/bb220820(v=office.12).aspx) for documentation on `ActiveWorkbook`. Let me know if you need further clarification :) – Michael S Priz Jul 27 '15 at 17:26
  • @MichaelSPriz, Got it thanks Mike. Using the above code by Mielk in the personal macros didnt work, but using it in the 'this workbook' file works perfectly. So switching to Activeworkbook would allow me to use it across multple workbooks? – Jonathan Jul 27 '15 at 17:56
  • @Jonathan I am going to transfer this line of discussion to a separate answer so that I may be more thorough :) – Michael S Priz Jul 27 '15 at 18:04
  • @mielk, Hi Mielk, is there a way to not have the header included? (first row of each sheet) – Jonathan Aug 01 '15 at 18:22
2

I feel your comments warrant me posting this as an answer so that I may be a bit more thorough. This is meant only to add to the answer provided by mielk!

The object hierarchy in excel is roughly summarized by "An Excel Application owns workbooks. An Excel Workbook owns Worksheets. An Excel Worksheet owns Ranges." For more info on that look here.

When you click on an excel file to open it you are effectively doing 2 things:

  1. Starting up an Excel "Application"
  2. Opening up a Workbook that that "Application" will "own"

When you open up subsequent Excel files, Excel will skip step one and simply open a workbook in the Excel Application that is already running. Note this means that similar to how a Workbook can have many Worksheets a single Excel Application can have multiple Workbooks that belong to it.

There are multiple ways to access these workbooks in VBA. One way is to use the application's Workbooks member much like you used a Workbook's Sheets member to access worksheets. Often though you simply want to access the Workbook that the user is currently editing/working on. To do this you can use ActiveWorkbook which is automatically updated for you whenever the user begins work on a different workbook.

Another Workbook you will often want to use is the workbook that "houses" the code you are running. You can do this by using ThisWorkbook. If you open up the VBA editor and look at the project viewer, you can even see a reference to ThisWorkbook! If you want your code to only update/alter the workbook that contains it then ThisWorkbook is the way to go.

As an example:

Let's say you have a macro to loop through all of the open workbooks and put the number of sheets each Workbook "owns" into some Worksheet in the "master" workbook.

You could do something like this:

Sub CountThem()
    Dim wb As Workbook
    Dim outputCell As Range
    Dim nextRow As Integer

    nextRow = 1
    For Each wb In Application.Workbooks
        wb.Activate
        ThisWorkbook.Sheets("MySheet").Cells(nextRow, 1).Value = ActiveWorkbook.Sheets.Count
        nextRow = nextRow + 1
    Next
End Sub

You would put this code as a module in the "Master" workbook.

Let me know if this clears things up for you! :)

Michael S Priz
  • 1,116
  • 7
  • 17
  • Yes it does! Thanks Mike!, So why is it I have to run the code by Miekl in the thisworkbook file? Can I change it to work in a personal macro module? – Jonathan Jul 27 '15 at 19:18
  • What do you mean by "personal macro module"? Do you mean one you created by clicking "Insert Module"? – Michael S Priz Jul 27 '15 at 19:24
  • I mean the .xlsb files, the ones that are always opening in vba editor. So I can use them without having to put the code into each workbook. – Jonathan Jul 27 '15 at 19:51
  • I am not sure I understand the terminology you are using. From your comments you have a master excel file you are copying data to correct? Is this what you are referring to when you say "the thisworkbook file"? – Michael S Priz Jul 27 '15 at 20:22
  • here i wil include a link: [http://i.imgur.com/e2g8VOB.jpg] . When I run the code in my personal macros section I get an error, when I run it in the workbook itself, its fine. Anyway my end goal is to be able to run it across a directory of excel files, and if possible put it into a master file. – Jonathan Jul 27 '15 at 20:50
  • So an xlsb file is almost the same as a regular old excel file. You will notice that there is a section under the heading "personalmacros.xlsb" called "ThisWorkbook". Any code in "personalmacros.xlsb" that refers to "ThisWorkbook" will be referring to the "personalmacros.xlsb". Presumably you were trying to access a sheet that was not in the "personalmacros.xlsb" workbook. – Michael S Priz Jul 28 '15 at 01:08
  • thanks Michael. Is there anyway I can apply the above code by Miekl to a directory of files? and have it all done at once? – Jonathan Jul 28 '15 at 13:40
  • The top answer to [this](http://stackoverflow.com/questions/579797/open-excel-file-for-reading-with-vba-without-display) should put you on the correct track. If not you should ask a new question and link me to it here, as we have already gotten way off topic from the original question you asked here ;) – Michael S Priz Jul 28 '15 at 14:49
  • Thanks Michael, sorry for going off track , you have been great help. Anyway if you have time here is the new link http://stackoverflow.com/questions/31686806/vba-code-for-directory-and-paste-to-master-sheet – Jonathan Jul 28 '15 at 20:50