This is my first post. I am currently working on a project at work which requires that I work with several different worksheets in order to create one mail master worksheet, as it were, in order to do a mail merge. The worksheet contains information regarding different purchases, and each purchaser is identified with their own ID number. Below is an example of what my spreadsheet looks like now (however I do have more columns):
ID Salutation Address ID Name Donation ID Name Tickets
9 Mr. John Doe 123 12 Ms. Jane Smith 100.00 12 Ms.Jane Smith 300.00
12 Ms. Jane Smith 456 22 Mr. Mike Man 500.00 84 Ms. Jo Smith 300.00
What I would like to do is somehow sort my data so that everythign with the same unique identifier (ID) lines up on the same row. For example ID 12 Jane Smith - all the information for her will show up under her name matched by her ID number, and ID 22 will match up with 22 etc...
When I merged all of my spreadsheets together, I sorted them all by ID number, however my problem is, not everyone who made a donation bought a ticket or some people just bought tickets and nothing us, so sorting doesn't work.
Hopefully this makes sense.
Thanks in advance.
You can do this in Excel VBA. If you haven't used VBA in Excel before, see the link below to see how to access it.
http://msdn.microsoft.com/en-us/library/ee814737.aspx
Make sure you backup your spreadsheet before trying any of this in case something goes wrong!
I wrote something up that will copy data from your secondary worksheets into your main worksheet. Just open the VBA editor, and paste in the code.
Next, edit the ConsolidateWorksheets() function so that it has the right names for your sheets. If you have additional sheets, declare them and add another line that calls the ProcessWorksheet subroutine for the added sheet.
This code will copy data from your tickets and donations worksheet into your main worksheet when it finds a matching id. If there isn't a matching id, it doesn't copy anything for that row.
Option Explicit
Sub ConsolidateWorksheets()
'declare the worksheets you are using
Dim mainWks As Worksheet
Dim ticketsWks As Worksheet
Dim donationsWks As Worksheet
'set the worksheet names
Set mainWks = ThisWorkbook.Worksheets("Sheet1")
Set ticketsWks = ThisWorkbook.Worksheets("Sheet2")
Set donationsWks = ThisWorkbook.Worksheets("Sheet3")
Call ProcessWorksheet(mainWks, ticketsWks)
Call ProcessWorksheet(mainWks, donationsWks)
End Sub
' copies data from the otherWks to the mainWks
Sub ProcessWorksheet(mainWks As Worksheet, otherWks As Worksheet)
Dim i As Integer
Dim rowId As Integer
Dim otherRowIndex As Integer
Dim otherLastColIndex As Integer
Dim lastRowIndex As Integer
Dim pasteColStart As Integer
Dim pasteColEnd As Integer
' figure out the last row in the main sheet
lastRowIndex = mainWks.UsedRange.Rows.count
otherLastColIndex = otherWks.UsedRange.Columns.count
' figure out where to copy and paste from
' this assumes that the id row is always the first row in every sheet
pasteColStart = mainWks.UsedRange.Columns.count + 1
pasteColEnd = pasteColStart + (otherLastColIndex - 2)
' copy column headers
otherWks.Activate
otherWks.Range(Cells(1, 2), Cells(1, otherLastColIndex)).Copy
mainWks.Activate
mainWks.Range(Cells(1, pasteColStart), Cells(1, pasteColEnd)).PasteSpecial
' loop through all the rows of the main sheet
For i = 2 To lastRowIndex
' get row id from first cell in current row
rowId = Cells(i, 1).Value
'lookup row id in other worksheets
otherRowIndex = FindIdRowInWks(otherWks, rowId)
If otherRowIndex <> 0 Then
otherWks.Activate
otherWks.Range(Cells(otherRowIndex, 2), Cells(otherRowIndex, otherLastColIndex)).Copy
mainWks.Activate
mainWks.Range(Cells(i, pasteColStart), Cells(i, pasteColEnd)).PasteSpecial
End If
Next i
End Sub
' loops through the given worksheet, looks for a given id in the first column
' and returns the row index where the id was found. returns 0 if nothing found.
Public Function FindIdRowInWks(wks As Worksheet, idToFind As Integer) As Integer
Dim lastRow As Integer
lastRow = wks.Range("A" & Rows.count).End(xlUp).Row
Dim rowNumber As Integer
rowNumber = 0
Dim i As Integer
For i = 2 To lastRow
If (Cells(i, 1).Value = idToFind) Then
rowNumber = i
End If
Next i
FindIdRowInWks = rowNumber
End Function
Hope that helps!
You can do this in 3 Steps without VBA:
1) Create new worksheet
2) On New Sheet get a consolidated list of ID & Salutation
For XL2007 see Remove Duplicates, for XL2003 see advanced filter.
3) Create a Setup Like so using vlookups and iferror to grab the values you want based on the relevant sections from the original sheet. See the image and the vlookup formula in the formula bar
Related
I have 2 worksheets (WS1 is "ImportWS" and WS2 is "Disco + BLScope", there are names in column A in both worksheets and both have a column B with a value like Jumps high or still cant jump high). I need to compare WS Disco + BLScope column A with ImportWS Column A and if a match is found then copy the adjacent value in WS ImportWS Column "B" to WS Disco + BLScope Column "B" on the respective matched row and then continue to see if there are more updates in WS ImportWSand repeat.
In a perfect-world, a pop up would appear at the end stating how many updates were found/made.
I have tried Vlookups but that doesn't work as I want to keep the value in WS Master if a match is not found.
I found this code (which does the core of what I need) which I tried to adjust but I get a run time error on the "lassrowAdd" line:
Sub CopyAdjacent()
Dim colStatus, lastrowAdd, lastrowRemove As Integer
colStatus = 2
lastrowAdd = Sheets(“ImportWS”).Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To lastrowAdd
If Sheets(“ImportWS”).Cells(i, 1).Value = Sheets(“Disco + BLScope”).Cells(i, 1).Value Then
Sheets(“Disco + BLScope”).Cells(i, colStatus).Value = Sheets(“ImportWS”).Cells(i, colStatus).Value
End If
Next
End Sub
So basically the end result would be:
The worksheet Disco + BLScope would have an updated value in the respective column B rows if an update is found in worksheet ImportWS.
At the end of the macro a popup to appear (this is totally optional) stating how many updates were found/made.
Hope that made sense, been trying for hours but cant crack it, your help would very much be appreciated.
I am trying to expand my annual planning document to give me more information. Currently however I am stuck.
My current Sheet is laid out as follows:
I need to create a second sheet that concatenates the client name with each column heading there is a "yes" value in, as its own separate line.
Example 1 in the new sheet would become:
Example 1 - Annuals
Example 1 - Xero Fee
I had tried a copy and paste Macro, based on a quantity column counting the rows that include text. This gave the desired amount of client names in a new sheet but I was unable to work out how to include the "concatenate" part of this problem to it.
Public Sub CopyData()
' This routing will copy rows based on the quantity to a new sheet.
Dim rngSinglecell As Range
Dim rngQuantityCells As Range
Dim intCount As Integer
' Set this for the range where the Quantity column exists. This works only if there are no empty cells
Set rngQuantityCells = Range("G1", Range("G1").End(xlDown))
For Each rngSinglecell In rngQuantityCells
' Check if this cell actually contains a number
If IsNumeric(rngSinglecell.Value) Then
' Check if the number is greater than 0
If rngSinglecell.Value > 0 Then
' Copy this row as many times as .value
For intCount = 1 To rngSinglecell.Value
' Copy the row into the next emtpy row in sheet2
Range(rngSinglecell.Address).EntireRow.Copy Destination:=Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Offset(1)
' The above line finds the next empty row.
Next
End If
End If
Next
End Sub
If your goal is to get from this:
...to this (or that):
...then what you want to do is called an Unpivot.
How to Unpivot "crosstab-style" data:
You can find the steps written out on a question I answered a week ago, and there's a more detailed explanation and steps over here.
Let me know if you have any questions!
Yeah, maybe I used this as an excuse to practice using Screen2Gif, but it sure helps demo a point! :-)
🇨🇦
I have a table "RawData" in excel I would like to filter. Column A has a name, and Column B has a number. I would like to copy the data to a different table, "LoadingData", if the name matches up with a specific number. I have the corresponding names/numbers in a different tab "ShiftData" within the worksheet.
EX. If John Smith has a 2 in the column next to him, copy the whole row to sheet "LoadingData". If John Smith has a 4 in the column next to him, do not move his data.
I tried using a VLOOKUP function, but I think what I'm trying to do is more complicated than that. Any help would be appreciated!
Sub CopyData()
Const cValuetoCheck = 2
Dim rngData As Range, rngLoad As Range
Set rngData = Worksheets("shiftdata").Range("B1")
Set rngLoad = Worksheets("loadingdata").Range("A1")
While Not (IsEmpty(rngData))
If rngData = cValuetoCheck Then
rngData.EntireRow.Copy
rngLoad.EntireRow.PasteSpecial
Set rngLoad = rngLoad.Offset(1, 0)
End If
Set rngData = rngData.Offset(1, 0)
Wend
End Sub
I'm working on a really large excel sheet which is basically a list of users along with the applications they use. Now the problem is that there are over 60000 users with atleast 10 applications each. So its a huge sheet. 2-3 times a week I need to extract the details of the applications used by certain specific users. Sometimes it's 2 users. Sometimes its 10 users. But due to the size of the spreadsheet, this activity takes me forever (1-2 hours).
Now, the sheet is structured in the following way.
StaffId Name DeviceNo Location ApplicationCount+ AppID Application Name
12345 John Doe DSK-982333 Mespil Road 24+
123 Adobe Acrobat
234 WinZip
345 Google Chrome
The + sign here is to indicate the grouped rows.
Is there anyway for me to use PowerPivots to extract this information?
One approach would be to:
Create a copy of your spreadsheet in a new workbook.
Add another worksheet in the workbook that contains the StaffId (in column "A") of the people you want to filter for.
In the VBA editor, insert a new module and add the following code:
Sub FilterForUsersOfInterest()
Dim BigSheet As Worksheet
Dim ListSheet As Worksheet
Dim lastCell As Range
Set BigSheet = ActiveWorkbook.Sheets("ListOfApplications") 'Change the sheet name here to match your main data tab
Set ListSheet = ActiveWorkbook.Sheets("ListOfUsers") 'Change the sheet name here to match your sheet with the users of interest this time round
'Find the last used row on the worksheet
Set lastCell = BigSheet.UsedRange.Item(BigSheet.UsedRange.Cells.Count)
'Copy the values for Staff Id down all the rows
For iRow = 2 To lastCell.Row
If BigSheet.Range("A" & iRow) = "" Then
BigSheet.Range("A" & iRow) = BigSheet.Range("A" & iRow - 1)
End If
Next iRow
'Now work your way back up the rows, deleting any rows where the StaffId is not found in the current list of "users of interest"
For iRow = lastCell.Row To 2
If Application.WorksheetFunction.CountIf(ListSheet.Range("A:A"), BigSheet.Range("A" & iRow)) = 0 Then
BigSheet.Range("A" & iRow).EntireRow.Delete
End If
Next iRow
End Sub
Excel 2007
I'm trying to run a VBA script that will copy a list of sales Ledgers from one worksheet titled MSL with the columns DATE, INVOICE NO, COMPANY NAME, TOTAL, SUB-TOTAL, NETT, VAT.
1st problem i'm having is i only want to copy rows 2 and onward which contain a record and this number will change each month depending on sales.
e.g. Jan has 30 rows
Feb has 24 rows
Mar has 40 rows
Next i need to paste the data in to a new worksheet titled "SalesDB" with the same columns DATE, INVOICE NO, COMPANY NAME, TOTAL, SUB-TOTAL, NETT, VAT.
Next problem im having is the data is overwriting.
Thanks for any help
will be out for the next hour collecting kids from school
Assuming Worksheet MLS is like the following and Worksheet SalesDB is same format:
A B C D E F G
1 Date Invoice No Company Name Total Sub-Total Nett VAT
2
This code will grab data from MLS taking account of number of entries and add to SalesDB and avoid overwriting.
Sub CopyPasteSales
Dim salesData as range, targetRng as range
Set salesData = Worksheets("MLS").Range("A2:G" & Range("A1").end(xlDown).Row)
If Worksheets("SalesDB").Range("A2") = vbNullString Then
Set targetRng = Worksheets("SalesDB").Range("A2") //If no data in SalesDB start in row 2
Else
Set targetRng = Worksheets("SalesDB").Range("A1").end(xlDown).Offset(1,0) //If data already in SalesDB, find next free row
End if
salesData.Copy Destination:= targetRng
End Sub
Short and dynamic: (not tested, may contain typos)
Sub CopyData()
Dim src As Range, dest As Range
'set source, exclude first row
Set src = Worksheets("MLS").Range("A2").CurrentRegion.Offset(1, 0)
'destination is one row below last row
Set dest = Worksheets("SalesDB").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
src.Copy Destination:=dest
End Sub