5

I've got a spreadsheet full of names and peoples' roles, like the one below:

Role Name  Change
1     A     Yes
2     A     No
5     A     N/Ap
1     B     Yes
3     B     No
2     C     Yes
4     C     No

I have to come up with a spreadsheet like the one below:

     1        2        3        4        5        6
A   Yes                     
B                       
C                       

Basically, it should retrieve the information from the first spreadsheet and be layed out clearly on the second one.

There are way too many names and roles to do it manually. VLMOVE won't work and I've tried MATCH and INDEX.

4
  • 1
    I'm not an Excel guru, but this looks suspiciously like a Pivot table. Am I wrong? If not, try that approach. I don't have Excel 2007 installed anymore, but I'm sure you can find instructions online. Commented Dec 21, 2012 at 20:34
  • Got a quick link for me? Commented Dec 21, 2012 at 20:40
  • Just Google Excel 2007 pivot table Commented Dec 21, 2012 at 20:41
  • 1
    @user1922488 If you really insist on VBA, take a look at this post if you have doubts happy to help. :) Commented Dec 21, 2012 at 21:22

5 Answers 5

2

Alternative to @RocketDonkey (but thanks for more complete desired result!) could be to string together Role and Name (say in a column inserted between B & C in Sheet1 [because I think OP wants a separate sheet for the results]):

C2=A1&B2  copied down as required

then use a lookup in Sheet2!B2:

=IFERROR(VLOOKUP(B$1&$A2,Sheet1!$C$2:$D$8,2,FALSE),"")  

copied across and down as required.

This assumes the grid for the results (as in question) has been constructed (and that there are 7 rows with data - adjust $8 as necessary otherwise.)

Sign up to request clarification or add additional context in comments.

4 Comments

why would post an answer that is identical to mine? yes, given the fact that I missed the dollars signs (i didn't have XL on me to test) ... I find it odd that you would essentially provide the same answer as I, especially after making the comment on mine for edits.
Look at that ... I just sorted by oldest and sure enough you were there first. I either missed it entirely or we posted almost simultaneously, as I surely wouldn't have posted a duplicate answer! Many blessings during this festive season.
Ah ... thanks. I was probably typing my answer as yours posted.
A nice extension to the non-pivot table solutions would be to provide a means to have the result table automatically taken in account the addition of new roles and names to the initial list.
2

Agree with @Melanie that if you can force your data into a structure that can be interpreted as numbers (1 being yes, 0 being false, for example), Pivot tables are far and away the easiest way (since they will display numbers as the values - not the text). *(see below)

If you want to display arbitrary text, you could try this:

=IF(
    SUMPRODUCT(--($A$2:$A$8=F$1),--($B$2:$B$8=$E2),ROW($A$2:$A$8))=0,"",
    INDEX(
        $A$1:$C$8,
        SUMPRODUCT(--($A$2:$A$8=F$1),--($B$2:$B$8=$E2),ROW($A$2:$A$8)),
        3))

This checks to see if the SUMPRODUCT of the three columns totals 0 (which will happen when no combo of x/y is matched (like Name: C, Role: 5, for instance), and if so, it returns "". Otherwise, it returns the value in column Value.

enter image description here



*A ‘pivot table option’ would be to represent the Change as a number (eg as formula in D2 copied down). Then create a pivot table from (in the example) A1:D8, with fields as shown. Copy the pivot table to a different sheet with Paste Special/Values (though shown in F11:K15 of same sheet in example). Then in that other sheet select row starting with Name A and as far down as required, Replace -1 with No, 1 with Yes and 0 with N/Ap.

enter image description here

1 Comment

@pnuts Hey you did the work - drop this in yours instead and I'll send a +1 your way :)
1

AMENDED

You can use array formulas to reorganize your table, without having to change the its structure. Assuming the data is in the range A2:C8 on Sheet1 and the result table is to be in range A1:G4 on Sheet2, the following formula would be the first entry (role 1 and name A) in the result table.

   =IFERROR(INDEX(Sheet1!$A$2:$C$8,MATCH(B$1&$A2,Sheet1!$A$2:$A$8&Sheet1!$B$2:$B$8,0),3),"-")

The MATCH formula returns the row number in which the role/name combination 1A occurs. The INDEX function returns the contents of the cell at the row number found by the MATCH formula and the column number 3, i.e., the Change column of your data table. The IFERROR returns "-" if the role/name combination is not in the data table.

Be sure to enter the formula using the Control-Shift-Enter key combination. Then copy the formula to the remaining cells of the result table.

The data table on Sheet1:

data table on Sheet1

The result table on Sheet2:

result table on Sheet

3 Comments

@pnuts I think chuff and I were just showing the general concept of what you would do - to apply to a different sheet would just entail prefixing with a sheet name.
@pnuts Yeah, I agree - if the data can be represented as numbers, Pivot Table all day :)
Good point on the specification that the results would be laid out on the second table. I've amended my answer to take that into account.
1

Well since there's Excel-VBA tag, thought it would complete the solutions types by adding one in VBA :) The following code is not elegant, in any case you need to use code base, give it a try :)

Code:

Option Explicit

Public Sub sortAndPivot()
Dim d As Object
Dim ws As Worksheet
Dim sourceArray As Variant, pvtArray As Variant, v As Variant
Dim maxRole As Long
Dim i, j, k, m As Integer

    Set d = CreateObject("Scripting.Dictionary")
    Set ws = Worksheets("Sheet3") '-- set according to your sheet
    '-- you could enhance by using an input box to select the range
    sourceArray = Application.WorksheetFunction.Transpose(ws.Range("B3:D9").Value)
    '-- max role number
    maxRole = Application.WorksheetFunction.Max(ws.Range("B3:B9"))

    '-- find unique name list
    For i = LBound(sourceArray, 2) To UBound(sourceArray, 2)
        If Not d.exists(sourceArray(2, i)) Then
            d.Add sourceArray(2, i), i
        End If
    Next i

    ReDim pvtArray(d.Count, maxRole)
    pvtArray(0, 0) = "Name"

    '-- add unique names from dictionary
    j = 1
    For Each v In d.keys
        pvtArray(j, 0) = v
        j = j + 1
    Next

    '-- add unique Role number list
    For i = UBound(pvtArray, 2) To LBound(pvtArray) + 1 Step -1
        pvtArray(0, i) = i
    Next i

    '-- sort into the correct positions
    For k = LBound(pvtArray, 1) + 1 To UBound(pvtArray, 1)
        For m = LBound(pvtArray, 2) + 1 To UBound(pvtArray, 2)
            For i = LBound(sourceArray, 2) To UBound(sourceArray, 2)
                If pvtArray(k, 0) = sourceArray(2, i) Then
                    If pvtArray(0, m) = sourceArray(1, i) Then
                        pvtArray(k, m) = sourceArray(3, i)
                    End If
            End If
        Next i
        Next m
    Next k

    'Output the processed array into the Sheet in pivot view.
    Range("F2").Resize(UBound(pvtArray) + 1, _
    UBound(Application.Transpose(pvtArray))) = pvtArray

    Set d = Nothing
End Sub

Results:

enter image description here

3 Comments

@user1922488 If you are interested, give this a shot ;) and comment please.
@pnuts it doesn't harm to have as many different solutions as it can. More the merrier - OP then has a choice to choose which fits best for the occasion! Ofcourse a sheet formula based is less sweaty and more sweet - given performance is high + non-volatile functions usage for a larger data set!
PNUTS when we post, we post answers that we think the best. There are badges like tenacious and unsung hero!
1

There is another way to go about it without VBA. If you create another column that concatenates the first two in the first spreadsheet, like so:

Role Name  Change  CheckColumn
1     A     Yes    1A
2     A     No     2A
5     A     N/Ap   5A
1     B     Yes    1B
3     B     No     3B
2     C     Yes    2C
4     C     No     4C

Then you can use the Offset and Match functions together to find the change in the 2nd sheet. So assuming your data is laid from cell A1, the formula in cell B2 would be:

=iferror(offset(Sheet1!$A$1,match(B$1&$A2,sheet1!$D:$D,0),2),"")

Alternatively, if you put the concatenated column in sheet1 before the role column, you can use vlookup in sheet2, with the formula being:

=iferror(vlookup(B$1&$A2,sheet1!$A:$D,4,false),"")

1 Comment

@pnuts - thanks. I am running a fever and didn't have XL on me... so I missed a few things :) will edit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.