I have a table, let's call it my Individuals Table, much like the one below, containing a column of individuals along with their corresponding codes listed in an adjacent cell. Codes for each individual are all listed within the same adjacent cell next to the individual's name, and separated by a carriage return.
Example table
What I'd like to do is the following:
Run through the code cell for each individual
For each code in the individual's code cell, check if this code exists in a separate Codes Table
If the code exists in the Codes Table, add n+1 to the total count for that code in an adjacent cell and add the individual's name to the list of individuals with that same code in another adjacent cell.
If the code does not exist in the Codes Table, add the code to the Codes Table, add n+1 to the total count for that code in an adjacent cell and add the individual's name to the list of individuals with that same code in another adjacent cell.
Result of running the algorithm on the example table
If a similar program can achieve the same results, then I'm open to that too.
I try to give you a possible solution, by minimizing the use of VBA code.
As starting point I would do is rearranging codes for every individuals. Keeping more codes in a single cell separed by a return it is not as easy to manage like having a single code for each cell. Of course I will keep each code associated with each individual. A way to do it is with your data is by using the formula substitute and replace the returns characters with a semicolon. The formula works this:
=SUBSTITUTE(B2,CHAR(13),CHAR(59))
B2 is the cell where you are converting returns to semicolon. You will then use this formula for all values in your B column.
Once you have replaced returns with semicolon, copy and paste values and then with the function "Text to Columns" in Data tab you will convert each cell to a series of columns (depending on how many codes you had listed in the original cell of your sheet). Now you will be in a situation where the first column you have the names of individuals, and then on the same row in the subsequent columns you have all associated codes, like in the picture here below:
In order to create a complete list of all codes you can easily copy all columns with codes. Paste the codes in a suitable space (I suggest in a new worksheet), and then with some copy and paste jobs put all codes under the same column. Select all codes and with the button "Remove Duplicates" always in the Data tab you will have a list of all unique codes included in your original table.
Then you can copy and paste the column with all unique codes you created under your "Codes" column. Now you can count the codes in the converted table with this formula:
=COUNTIF($B$1:$C$4, D2)
Where first argument of COUNTIF refers to the codes in the converted table and the second argument is a code in your column "Codes" where you pasted the unique codes.
Now as far as I know there is no function in Excel to create a list of names separated by commas (but I would be glad to discover that it exists if anybody knows!!!). Therefore I created a custom one with some VBA code with the name List Individuals:
Function ListIndividuals(refCode, NameRange As Range, CodesRange As Range) As String
'Check size in row number of NameRange and CodesRange is same, otherwise give error
If NameRange.Rows.Count <> CodesRange.Rows.Count Then
ListIndividuals = CVErr(xlErrRef)
Exit Function
End If
result = ""
For Col = 1 To CodesRange.Columns.Count
For n = 1 To CodesRange.Rows.Count
If CodesRange.Cells(n, Col).Value = refCode Then
If CodesRange.Cells(n, Col).Value <> "" Then
If result = "" Then
result = NameRange(n)
Else
result = result & ", " & NameRange(n)
End If
End If
End If
Next
Next
ListIndividuals = result
End Function
So last step is to use this formula under your "Individuals" cells as follows:
=ListIndividuals(D2,$A$13:$A$16,$D$13:$E$16)
Where first argument is the Code, the second one is the list of individuals in the converted table (it should be the first column), then the third one are the columns with the codes in the converted table. As a result of this custom formula you will have the list of individuals separated by commas.
All above works on my computer, but if you need more information, please do not hesitate to contact me.
Related
I have a dashboard (image below) where I manually add entries. Then there is a log (image below) where all entries are recorded with the help of IF and Vlookup functions.
I need a code so so that every output cell in the log finds through all the entries in the dashboard and gives the answer. I think loop for vlookup will be used.
[Edit]
Consider the Dasboard table as a discrete table where manually entries are posted.
Consider log table as a continues table where record of every hour for each date is kept. The entries from Dashboard table get posted to the log table. New Image attached New Image
I have entered this function in output column in the log table:
=IF( AND(H3=$B$3,I3>= $C$3,I3<$D$3) ,$E$3,0) + IF(AND(H3=$B$4,I3>=
$C$4,I3<$D$4) ,$E$4,0) + IF (AND(H3=$B$5,I3>= $C$5,I3<$D$5), $E$5,0)
This works fine for me for plotting the entries but the problem is for every row in the dashboard i have to add a new IF-And function in the above. so for example if i want to add the 4th row of dashboard to be sync with the log ill have to add
+If(AND(H3=$B$6,I3>=$C$6,I3<$D$6),$E$6,0)
I want every row in the dashboard to add automatically somehow with a loop like:
i = variable
= If (AND(H3=$B$i,I3>= $C$i,I3<$D$i), $E$i,0)
Only one i will be greater than 0 while the rest will be zero. so the function should return me the sum of all i rather than just the last iteration.
Maybe just filldown the formula manually? if insist with macro, something like
Sub test()
Range("K3").Value = "X"
Range("K3:K10").FillDown
End Sub
replace "X" with your formula, keep the " "
replace K10 with how far down you want
----edit----
let me break down below for you,
match(H3,B:B,0), will find the correct row in B that = H, in H3 case it finds B3
INDEX(B:E,MATCH(H3,B:B,0),2) -> now it find B3, index let you find C3 (notice the 2,3,4 in later codes, it means the column from B3)
and (I3>=...,J3>=...)now we got both start and end time, we use I and J to compare
if 3. is true, lookup the output column, else 0
=IF(AND(I3>=INDEX(B:E,MATCH(H3,B:B,0),2),J3>=INDEX(B:E,MATCH(H3,B:B,0),3)),INDEX(B:E,MATCH(H3,B:B,0),4),0)
Maybe I have used the wrong phrase to search but I have not been able to find a solution to the following challenge for Excel/VBA:
In Sheet 1 I have a database of order data from cells A1 to F10. Each row contains data for one order. Column A contains the order number.
As first step I, in sheet 2, wish to make a search on the order number and retrieve all data for that order into cells A5 to F5 in sheet 2.
After reviewing the data (and running another macro to recalculate the sales price) I wish to have the revised data replace the original data in sheet 1.
Can anyone help me with this?
Thank you in advance!
The 1st part does not need macro.
vlookup (fkeres magyarul) is your function. If you put this function in A5-F5 fields in sheet 2, looking for a given order number, in Sheet1 $A$1:$F$10, entering the required column number, asking exact match (FALSE), it works nicely. I entered the functions parameters in my previous sentence.
The 2nd part needs macro which makes Copy Paste back.
OR
Look for the requested order row in sheet2 A5 cell with MATCH (HOL.VAN magyarul) function, like =MATCH(A1;Sheet1!A1:A10;0)
and put INDIRECT (INDIREKT magyarul) function, like =INDIRECT("Sheet1!B"&A5;TRUE) in B5, etc.
In this case the Copy-Paste back macro is (starting from Sheet2):
Myorder = Range("A5").Value
Range("B5:F5").Select ' A5 is the row number of order, not the order No
Selection.Copy
Application.Goto Reference:=Worksheets("Munka1").Range("A" & Myorder)
ActiveSheet.Paste
...or very similar
I have checked many possible answers but none match it close enough.
Our fixtures inventory is on Excel.
1) I use a scanner to check the tag numbers on inventory items which puts it in another sheet.
2) Currently after I finish a room of furniture I sort the numbers in numeric order than move to the main sheet and copy the tag numbers (already in numeric order) and description and past it into the next column.
3) I then compare the numbers to see that they match.
I can create a macro to copy and paste the first number row but it won't do the next one.
Also when recording the macro I am coping the tag number from the cell and pasting it in search, when it matches I copy and paste the matched cell (tag number) and next cell to it ( description of item) to my target cell.
But I am not sure the macro is doing the search or just using what I set to copy.
Inventory sheet Column A = room number Column D=inventory tag Column E= description.
Example of what I want it to do:
I scan in product code 67-12345. [would be in column D sheet = inventory check}
I want the computer to move to the Inventory sheet
do a search for that tag number
When it gets a match [from column D in sheet = inventory]
copy and paste that cell and the one next to it [column D,E as well as column A (all on the same row) sheet = inventory] into sheet inventory check = [column D (D=D), E (E=E)and(C=A)
note: {info copied from A Inventory sheet into C inventory check sheet}*
Then go to the next row in [column D sheet = inventory check] and if populated continue the process.
I can live with having to run the macro for each line check, it just means running it 40 or 50 times per room.
I hope I have not made this too confusing in trying to explain it completely. Any help would be appreciated. I'm competent in Visual Basic for not overly complicated stuff. Also I use EXCEL 2013
I work in sourcing and I'm trying to look through a list of cells that contain part numbers and their description, but only pull the part number from the cell and place it in another column.
The part numbers have one of 10 possible prefixes (i.e. ABC, DDA, GHF, AH, etc.). The cells may look something like this:
Tire Pressure ABC123873 Monitor
Oil Life ABC849999999021 gauge
Air conditioner GHF211 maintenance
And I want to be able to search that entire list and only pull the following information into another column:
ABC123873
ABC849999999021
GHF211
As you can see from above, the challenge is that the part numbers are all different lengths and have no particular convention to them. The only thing you know about them is that they can have one of ten possible prefixes as I mentioned above (ABC, GHF, etc.).
The current solution I have looks something like this:
C2=FIND("ABC", A2)
D2=FIND(" ", A2, C2)
E2=MID(A2, C2, D2)
Where cell A2 contains the complete part number and description, C2 finds the beginning location of the part number by searching for its prefix, D2 finds the ending location of the part number by searching for a space, and then E2 pulls the substring between those two locations.
As you can see, this isn't a very robust solution and it only allows me to search for parts that start with ABC. I want to be able to search for all 10 possible prefixes (ABC, DDA, GHF, AH, etc.) but that does not work. I tried the approach below:
C2=FIND({"ABC", "DDA", "GHF", "AH"}, A2)
But that only searches for the ABC parts and disregards the other prefixes. Any help you all can offer will be greatly appreciated!!
This is how I would do it. I created a list of prefixes to search in column G. You could even put them on a separate page to keep it cleaner.
=MID(A1,FIND(G1:G2,A1,1),FIND(" ", A1, FIND(G1:G2, A1, 1))-FIND(G1:G2,A1,1))
I only tested two prefixes but just change G1:G2 to G1:G10 and put all you prefixes in them. The formula looks in A1. The first FIND finds the beginning character number. The rest of the equation is calculating the end of the product number minus the beginning which returns the amount of characters to return. Its important to know that MID isn't wanting the beginning and end character. It wants the beginning character and the number of characters after that to return. So FIND(" ", FIND(G1:G2, A1, 1)) does not work as it returns too many characters. Give it a try.
Oh and don't forget to do Ctrl+Shift+Enter to enter the array formula
The VBA answer would be
Sub findProductCode()
' Variable Declarations
Dim productName As String
Dim productArray() As String
Dim wordCount As Integer
' Sets the active sheet to use
' Change Sheet1 to the name of your sheet
With Sheets("Sheet1")
' Selects the first cell to check
' Change A1 to the first cell with data
Range("A1").Select
' Loops through all rows until an empty row
' It will end if you have any empty rows in the midle of data
Do Until IsEmpty(ActiveCell)
' Reads text out of the cell
'Change A to the proper column
productName = Range("A" & ActiveCell.Row).Text
' Splits the string into individual words
productArray = Split(productName, " ")
' Loops through array to find the product number
For wordCount = LBound(productArray) To UBound(productArray)
' Check if the word has the desired 10 prefixes
' Add more Or Left(productArray(wordCount), 3) = "xxx" until you have 10 of your prefixes you need
If Left(productArray(wordCount), 3) = "ABC" Or Left(productArray(wordCount), 3) = "GHF" Then
' Sends the product number to its cell
' Change B to the correct destination Cell
Range("B" & ActiveCell.Row).Value = productArray(wordCount)
End If
Next
' Increments the active cell to the next cell down
ActiveCell.Offset(1, 0).Select
Loop
End With
End Sub
If you don't know how, you need to enable the developer tab in excel. File->Options->Customize Ribbon Add the Developer to the Ribbon. The save your worksheet as .xlsm It is the macro enabled workbook. Then go to the developer tab, Choose "Visual Basic" and double click "ThisWorkBook". Paste the code in. You can run the code from there for a one time deal or you can create a button on the sheet that you can run this macro whenever you want.
To add a button, go back to the sheet you want the button on. On the developer tab select Insert and choose the first form control Button. Draw the button on your sheet and a dialog box will appear. select the findProductCode macro and select OK. Now every time you click the button it will run the macro.
This isn't the prettiest formula, but it should get you on your way. There's definitely a VBA solution, if you're interested in a macro instead of a formula.
Assuming your Tire Pressure ABC123873 Monitor is in A1, enter this into B1:
=MID(SUBSTITUTE(SUBSTITUTE(A1," ",";",1)," ","-",1),SEARCH("ABC",SUBSTITUTE(SUBSTITUTE(A1," ",";",1)," ","-",1)),SEARCH(" ",SUBSTITUTE(SUBSTITUTE(A1," ",";",1)," ","-",1))-SEARCH("ABC",SUBSTITUTE(SUBSTITUTE(A1," ",";",1)," ","-",1)))
How it works, is it takes your A1, and first uses Substitute. I substitute the first and second [space] for ; and -. (Note, if there are more spaces than two, this will run into issues). Then, I just use Mid to extract the part of the cell starting with ABC and going until it hits the space. If you don't have "ABC" starting the values you want, you need to adjust the Search("ABC"... part (or use an array there). I am still working on it, but hopefully this helps give an idea.
I'm new to Excel and the journey has been good so far, but I haven't been able to resolve this particular issue by myself. I'm dealing with a table as under:
Essentially, I'm looking to refer to the array of tags in columns from B3:E6, and do the following:
Create a "Unique Tags" column: Create a unique list of "tags" in column H by removing duplicates.
Create a "Maximum Marks" column: Look for each of the unique tags in the array in each row, and return the marks from the marks column in the same row. If the tag appears in multiple rows. the sum of the corresponding marks in these multiple rows should be returned in the maximum marks column in column I. For example, 'EASY' appears in E3 as well as E5. Thus in the 'Unique Tags' List 'EASY' should correspond to Maximum Marks = 4 (2+2).
I could do this manually using formulas such as SUMIF, but I'm looking for a way to automate it since I might have to do this operation for a similar dataset with additional rows & columns. I'm open to VBA solutions as well but would prefer some sort of formula.
I hope I've explained it well enough! Thanks and looking forward to your inputs.
One way to do this is create a function that returns the array of your unique cells and then multiplies them all by matches in your Marks column.
Create the unique cells with this array function. Note this function uses the Dictionary object. In the VB Editor, go to Tools > References, and make sure Microsoft Scripting Runtime is selected.
Public Function UniqueValues(aRange As Range)
Dim DictValues As New Dictionary
Dim cll As Variant
Dim aryResults() As String
For Each cll In aRange
If Not DictValues.Exists(cll.Value) Then DictValues.Add cll.Value, "":
Next
UniqueValues = DictValues.Keys
Set DictValues = Nothing
End Function
Enter in cell H3 and press CTRL SHIFT RETURN (as it's an array function)
=TRANSPOSE(uniquevalues(B3:E6))
and drag down to H15 or beyond
We have to use TRANSPOSE as the array comes out in a row from the function.
Next we need to find the matching cells and multiply. Here in C15 enter the formula below
=INDEX(SUM((($B$3:$E$6=H3)*1)*$F$3:$F$6),1)
Drag this down to H15.