I have a list of >100,000 diagnosis codes in a .XLS document and need to extract from this all codes that are relevant to a number of specific diseases.
What I would like to be able to do is include all 100,000 diagnostic codes in Column A, diagnostic labels in column B, and then have a "search term" cell (e.g. C1) in which I can write a word such as "fracture".
I would then like all the diagnostic codes including the string "fracture" to appear in column D.
Is there a simple way of doing this in Excel? I have looked online without much success but this might be because I'm not certain where to start. Conditional formatting hasn't helped as it's still unmanageable to scroll through 100,000 codes even if they are highlighted nicely.
Any initial thoughts or tips as to what I could try searching for would be very welcome.
Sample dataset:
238 Fracture of proximal humerus
202 Aortic stenosis
990 Chronic obstructive pulmonary disease
302 Hip fracture
182 Recurrent fractures
094 Marfan syndrome
298 Diabetic retinopathy
We can use a helper column to find the matching rows. In E1 enter:
=MATCH("*" & $C$1 & "*",B:B,0)
and in E2 enter:
=IFERROR(MATCH("*" & $C$1 & "*",INDEX(B:B,E1+1):INDEX(B:B,999999),0)+E1,"")
and copy down. Column E tells us where the matches are.. Then in D1 enter:
=IFERROR(INDEX(A:A,E1),"")
and copy down:
This is a fairly standard way to do a keyword search.
I realize you didn't ask for a filter but if you are open to a slightly different solution this seems to work well. Column A title and values should start at cell A2. Then type your search term in cell B1. It will also filter with wildcards and is case insensitive (i.e. show fracture, Fracture, fractures, Fractures, fractured, Fractured).
Option Explicit
Sub Filter()
Dim MyArray() As Variant
Dim MyNewArray() As Variant
Dim i As Long
Dim item As Variant
Dim FilterRange As Range
With ActiveSheet
Set FilterRange = .Range(.Cells(2, 1), .Cells(.Rows.Count, 1).End(xlUp))
MyArray = Application.Transpose(FilterRange)
i = 0
For Each item In MyArray
If UCase(item) Like "*" & UCase(Range("B1")) & "*" Then
ReDim Preserve MyNewArray(i)
MyNewArray(i) = item
i = i + 1
End If
Next item
.Range(FilterRange.Address).AutoFilter Field:=1, Criteria1:=MyNewArray(), Operator:=xlFilterValues
End With
End Sub
Additionally, you could add the following in the Worksheet object so you don't have to click a button to run the macro:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Application.Intersect(Target, Range("B1")) Is Nothing Then
Call Filter
End If
End Sub
Honestly, you can achieve the same thing with Filter > Text Filters > Custom Filter. You can use wildcards, too. :)
Let's say you want to search the term contained in C1 in column B.
You can try using this in A
=IF(C1<>"",IFERROR(FIND(C1,B1,1),0),0)
This will return a number if the text in C1 is present, else a 0.
You can then set D to be
=IF(A1>0,B1,"")
You will obtain this
I am putting the string to be searched for in the first row.
In row 2, I do a string match to get the first instance of a match for C1 in column A.
C2 =INDEX($A:$A,MATCH("*"&C1&"*",$A2:$A$100,0)+1)
Then find the next match starting from the array with row that matches C2 as the first row. I am fixing the last row as A100 which you can change.
C3 =INDEX($A:$A,MATCH("*"&$C$1&"*",INDIRECT("A"&MATCH(C2,$A:$A,0)+1&":A100"),0)+MATCH(C2,$A:$A,0))
Copy the formula down as required. Then copy columns across as required.
You can wrap the formula using IFERROR to suppress N/As.
You can also used an advanced filter in Excel by going to Data|Advanced:-
Note that the column headers in C1 and D1 must match the column headers in A1 and B1.
You can also adopt a DIY approach with:-
=IFERROR(INDEX(B:B,SMALL(IF(ISNUMBER(SEARCH($H$2,$B$1:$B$100000)),ROW($B$1:$B$100000)),ROW(1:1))),"")
assuming the search term is in H2, starting in say J2 and pulled down as necessary. This may be a little slow with 100K terms but is usable. Must be entered as an array formula with CtrlShiftEnter
I have been learning VBA for a while but there is one issue that I have been facing that I was not able to figure it out until know.
I want to be able to name a column using VBA, so I can use it later it as a reference column (using INDEX function) in other cells/columns.
I know to how to name a column that is fixed. But that is not what I am looking for.
Example of my issue:
This month I am naming column D as TotalAmount.
The VBA code can be:
ActiveWorkbook.Names.Add Name:="TotalAmount", RefersToR1C1:="=Sheet1!C4"
I will be referring to that column in other cells using the INDEX function.
However, next month I will be adding a new column (let's say previous month sales) just before Column D. So the new column that I want to name as TotalAmount the next month will be column E as opposed to D.
I know that the Column naming should not change when adding a new column and Column E will automatically become the TotalAmount column. However, I cannot rely on it because the excel sheet is accessed by different people and everyone is doing his own calculations.
So I tried this as well (I am sure it is stupid but hey I am still a noob) but it did not work :(
Sub Macro4()
Range("D1").Select
'(I can select the desired cell each month using the search function)
Dim i As Integer
i = ActiveCell.Column
ActiveWorkbook.Names.Add Name:="TotalAmount", RefersToR1C1:="=Sheet1!Ci"
End sub
So I will be very grateful if anyone could help me or guide me on this subject.
'i' is a variable so you cannot use that in quotes. In quotes, its just 'i' and has no value. try ActiveWorkbook.Names.Add Name:="TotalAmount", RefersToR1C1:="=Sheet1!C" & i
Not sure if this will resolve your problem though
You can get VBA to find the cell for you:
Sub SetNamedRange()
Dim rng As Range
Set rng = ThisWorkbook.Worksheets("Sheet1").Range("A1:Z1").Find("TotalAmount")
ThisWorkbook.Names.Add Name:="TotalAmount", RefersToR1C1:=rng
End Sub
The code searches A1:Z1 for the text "Total Amount" and sets the named range to that cell
I have a sheet with exact values (verified by =a2=b2 returning true).
However, =match(a2,b2,0) returns #N/A for some values, but not all.
All cells are formatted the same (I've tried General, Text, Number, etc.), and I have no idea where to go from here.
I don't know if I can upload my test workbook here so here's an image:
Maybe run a quick macro on the relevant cells in columns A and B:
Sub Clean_Up()
For Each r In Range("A2:B8")
r.Value = Val(r.Value)
Next r
End Sub
Adjust range (A2:B8 here) to suit.
Regards
I want to change references in formulas, from
=IF(N14="YES","A","B")
to
=IF($N$14="YES","A","B")
Fine on a single cell, my problem is that I have 20 x 1000 cells to edit like this. Is there a quick way to do it?
I don't think find and replace can be applied, as both row and column change (to be edited formulas spread over 20 rows and 1000 columns), so in the best case I need to do it 20+1000 times.
Select the desired range and run this code.
Sub RelativeToAbsolute()
Dim c As Variant
For Each c In Selection
If c.Formula <> "" Then
c.Value = Application.ConvertFormula(c.Formula, xlA1, , xlAbsolute)
End If
Next c
End Sub
Find and Replace. Find N14, Replace with $N$14, Look in Formulas.
If that does not fit the situation, edit your question and explain the situation in more detail, then post a comment.
First time posting for me and hoping to get some help with VBA for selective hardcoding.
I currently have a column into which a formula is set which returns either blank or a variety of text strings (the status of our company's orders).
I need to make a macro that looks into all the cells of that column and copy/pastes as value into that same cell only if the formula in that cell returns text string "Received". It should not affect the other cells where the formula is returning either blank or a different text string.
Would really appreciate your help. Please let me know if you need more info.
Thanks in advance,
Olivier
Put the following in the VBA project of your workbook:
Option Compare Text
Sub replaceThem()
Dim r As Range
Dim c
Set r = Range("B1:B3") ' use the actual range here
For Each c In r
If c.Value = "Received" Then c.Formula = "Received"
Next
End Sub
This will do what you asked. c.Value returns the value of the formula in the cell c, c.Formula replaces the formula. The Option Compare Text makes the comparison case-insensitive.