Extract cell references populated with values [VBA]
This article demonstrates a macro that returns cell references for cell ranges populated with values on a worksheet.
I have to combine 200 columns into one list. I know. I tried steps from 'Combine cell ranges into a single range while eliminating blanks' UDF, but looks like typing the formula itself is going to be a big deal. Any advice?
(To give a bit of a background, I am trying to compare 200 columns to one column of data and figured it would be easier if I combine all 200 into one column and then compare, it would be easy).
What you will learn in this article
- Create a macro that extracts cell references of populated cells in a worksheet.
- Save the answer from an inputbox to a variable.
- Loop through populated cells in a column.
- How to use the currentregion property with an object reference.
- Iterate through worksheet columns.
- Append values to a variable.
- Add values to a collection variable.
- Insert a new worksheet and save an object reference to a variable.
- Save the result to a given cell.
The following macro moves from column to column and checks for values. If a value is found, the current region property (Ctrl + A) is applied and the cell range address is saved. A new sheet is created and all unique distinct cell references are concatenated using a delimiting character into cell A1.
The current region is a range bounded by any combination of blank rows and blank columns. In other words, the macro creates cell references to all cell ranges populated with values.
VBA Code
'Name macro Sub ExtractAddresses() 'Dimension variables and declare data types Dim sht As Worksheet Dim CurCell As Range Dim Adr As New Collection Dim c As Single Dim Value As Variant Dim result As String, delch As String 'Show inputbox and ask for a delimiting character, save to variable delch delch = InputBox("Delimiting character:") 'The SET statement allows you to save an object reference to a variable Set CurCell = ActiveSheet.Range("A1") 'Iterate from 1 to the number of columns in your workbook using the FOR NEXT statement For c = 1 To Columns.Count - 1 'The SET statement allows you to save an object reference to a variable, in this case it is next populated cell in column A. It returns the last cell if column A has no populated cells. Set CurCell = CurCell.End(xlDown) 'Loop through following lines as long as cell saved to CurCell is not empty. Do While CurCell.Value <> "" 'Check if the length of the address of object CurCell with currentregion property is larger than 0 (zero) If Len(CurCell.CurrentRegion.Address) > 0 Then 'Enable error handling, an error occurs if a cell reference already exists in the collection variable On Error Resume Next 'Save address of currentregion property based on object CurCell to collection variable Adr Adr.Add CurCell.CurrentRegion.Address, CStr(CurCell.CurrentRegion.Address) 'Disable error handling On Error GoTo 0 End If 'Check if the CurCell row number equals the last row number in workbbok, if so stop Loop If CurCell.Row = Rows.Count Then Exit Do 'The SET statement allows you to save an object reference to a variable, in this case it is the last cell in column A. Set CurCell = CurCell.End(xlDown) Loop 'Save an object reference to the next cell to the right based on variable c to variable CurCell Set CurCell = Range("A1").Offset(0, c) 'Continue with next number Next c 'Iterate through each value saved in collection variable Adr For Each Value In Adr 'Add value to string variable result using variable delch as a delimiting character result = result & delch & Value 'Continue with next value in collection Next Value 'Add a new sheet and save a reference to variable sht Set sht = Sheets.Add 'Save text in string result to cell A1 sht.Range("A1") = Right(result, Len(result) - 1) End Sub
Where to put the code?
- Copy above VBA code.
- Press Alt + F11 to open the Visual Basic Editor.
- Select your workbook in the Project Explorer.
- Press with left mouse button on "Insert" on the menu.
- Press with left mouse button on "Module" to create a code module named Module1 that will be displayed below "Modules" in the Project Explorer.
- Paste VBA code to the code window, see image above.
- Return to Excel.
Note, save your workbook with file extension *.xlsm (macro-enabled) to attach the VBA code to the workbook.
How to use the macro
The animated image above shows how to run the macro.
- Press Alt + F8 to open the macro dialog box.
- Select ExtractAddresses.
- Press with mouse on button "Run".
- The macro asks for a delimiting character.
- The macro creates a new worksheet and populates cell A1 with cell references containing values. These cell references have a comma as a delimiting character.
Macro category
This article demonstrates how to add or remove a value in a regular drop down list based on a list […]
In this tutorial, I am going to show you how to add values to a drop down list programmatically in […]
This article demonstrates how to place values automatically to a table based on two conditions using a short macro. Cell […]
Excel categories
3 Responses to “Extract cell references populated with values [VBA]”
Leave a Reply
How to comment
How to add a formula to your comment
<code>Insert your formula here.</code>
Convert less than and larger than signs
Use html character entities instead of less than and larger than signs.
< becomes < and > becomes >
How to add VBA code to your comment
[vb 1="vbnet" language=","]
Put your VBA code here.
[/vb]
How to add a picture to your comment:
Upload picture to postimage.org or imgur
Paste image link to your comment.
If you do not mind the addresses for the ranges being presented in a different order, then this slightly shorter macro (which uses a completely different underlying method of obtaining the addresses) should also work...
One comment about your code. I changed the range C17:C21 to formulas (=F10 copied down) and your code worked fine. Then I forced C17 to return a #REF error (put =F1 in a cell, copied it up one cell to produce the error, and then copied that error cell to C17 and then ran your code again. Your code no longer reported the addresses for C17:C21. That is not the strange part, though (I think your Do statement may be filtering it out)... when I corrected the error by copying C18 up one cell to replace the error cell with a valid formula, your code still did not see the range C17:C21. Even after I used PasteSpecial to turn the formulas back to constants, your code still refused to see the range C17:C21. It is as though once the error was introduced to the range, your code somehow still "saw" the original error on subsequent runs even though it was no longer there! I have no explanation as to why that should be happening.
Just to mention, my code above has no problem with cells containing errors. Also, to make things easier to read, I set my code up to report relative addresses (that is, addresses without the $ signs).
One comment about your code. I changed the range C17:C21 to formulas (=F10 copied down) and your code worked fine. Then I forced C17 to return a #REF error (put =F1 in a cell, copied it up one cell to produce the error, and then copied that error cell to C17 and then ran your code again. Your code no longer reported the addresses for C17:C21. That is not the strange part, though (I think your Do statement may be filtering it out)... when I corrected the error by copying C18 up one cell to replace the error cell with a valid formula, your code still did not see the range C17:C21. Even after I used PasteSpecial to turn the formulas back to constants, your code still refused to see the range C17:C21. It is as though once the error was introduced to the range, your code somehow still "saw" the original error on subsequent runs even though it was no longer there! I have no explanation as to why that should be happening.
That is weird, I get a "Run-time error '13' Type missmatch error" (Excel 2010)
Do While CurCell.Value <> ""
Just to mention, my code above has no problem with cells containing errors. Also, to make things easier to read, I set my code up to report relative addresses (that is, addresses without the $ signs).
That is great, it is incredibly fast too! Really interesting approach.
This line is interesting:
Mid(Addresses, Len(Delimiter) + 1)
If you enter the Mid function in a worksheet, you can´t skip the num_chars argument. At least you need to type a comma.
Mid(text, start_num, num_chars)
becomes
Mid(text, start_num,)
But it always returns a blank cell. That is not the case when used in a macro.
[…] I have reused some parts of Rick Rothstein´s macro. […]