Set a named range based on search result Excel VBA - excel

I’m cleaning up some data that I have to clean up on a regular basis. Manual process driving me nuts.
I would like to set a range name, based on a search in a single column for two values. I'm using Excel 2007 if that assists.
I have read many threads but cannot find anything this specific. The closest thread was Excel VBA - Making a Named Range based on a found cell
For example Search column A and when you find the word department set that as the beginning of a range then continue to search column A and when you find the word Medium set that as the second point in the range.
So the search has located Department at A5 and Medium at A24 I now want to set that range (“A5:A24”) and give it a name. Any name will do Just need to see how it’s done?
Once I can do this I can work out other things I do with these found ranges such as delete them, Mark them, Copy them etcetera. The main point is defining them in the fist place.
I can do the search to find both and have been performing some loops to do the same but I have no clue in how to set the range based on that search result.
enter image description here

Here's an example of how to create a Range from two found cells in a column, using the row number of each and the column number in question.
This can be modified to handle cells in differing columns, depending on your use case. You can delete, mark, and copy combinedRng without having to name it.
Sub MakeMyRange()
Dim departmentRng As Range, mediumRng As Range
With ActiveSheet.Columns(1)
Set departmentRng = .Find("Department")
Set mediumRng = .Find("Medium")
End With
If Not departmentRng Is Nothing Then
If Not mediumRng Is Nothing Then
Dim combinedRng As Range
Set combinedRng = Range(Cells(departmentRng.Row, 1), Cells(mediumRng.Row, 1))
End If
End If
End Sub
If you really need to name the range, you could just do:
combinedRng.Name = "Test"

Related

How to output the Range (or row numbers) of a Formula in a specified cell?

Done a couple of hours of searching and haven't quite found what I'm looking for. I'm generally searching for things like "extract range value from formula" etc, but it doesn't really give me what I need. I even looked through the "Similar Questions" section as I typed out my title.
I rely entirely on searching for help with how to write snippets of VBA, and so far I've done fine until this point.
What I am trying to do:
OK I will clarify what I'm trying to do per suggestion from Pᴇʜ
I have a worksheet with thousands of lines of data (10k - 30k lines)
A previous employee has gone through these manually and manually entered Avg, Min, Max, Std Dev rows in between the raw data. The number of rows calculated above was not always consistent (sometimes 60 rows, sometimes 35, etc)
I am searching for the bottom or end row by searching for the text "Avg". This works well. Just find the cell with "AVG", then move up 1 cell and that's my end time.
What I am unable to do thus far is find the START row (using loops because there are MANY MANY of these. 30, 40, 50 for each worksheet. And probably 60 worksheets. So it would be inefficient to do this manually)
The only way this can be done reliably is to use what's available which is a formula - (example, =AVERAGE(C50:C110)). I will always choose the AVERAGE formula and it's always one set of ranges, not multiple sets (per example).
As I mentioned, I need to extract the start line from this formula and return it so i can use it somehow to specify which cell to copy and paste and do it in a loop over and over for every data set.
Hope this clarifies my situation. I was trying not to get too detailed, but I guess in hindsight that wasn't the greatest idea.
I apologize.
Scott_Craner's Link to arcadeprecint's answer should work. I just need to modify it to work with loops.
Tips?
If cell A1 contains the formula =AVERAGE(C50:C110) then
Debug.Print Range("A1").Precedents.Address(RowAbsolute:=False, ColumnAbsolute:=False)
will return C50:C110. If there are more precedent cells the addresses are comma separated eg =AVERAGE(C50:C110)+B5 results in C50:C110,B5.
Alternatively you can loop through the precedents areas to get all addresses separately.
Dim iArea As Range
For Each iArea In Range("A1").Precedents
Debug.Print iArea.Address(RowAbsolute:=False, ColumnAbsolute:=False)
Next iArea
To get the start and end row of a precedent address you can simply do some row calculation:
Dim rng As Range
Set rng = Range("YourAvrCell")
Debug.Print rng.Precedents.Address(RowAbsolute:=False, ColumnAbsolute:=False)
Debug.Print rng.Precedents.Row
Debug.Print rng.Precedents.Rows.Count + r.Precedents.Row - 1

Find currency and amount, also ID store in array and paste in Output sheet

I would like to find the text "Currency" in columns A or B, store all the currencies listed under Currency. Same process for Amount (Can be in an column)
Store values in an array. Then paste in Output Sheet. The currencies will already be listed in Output sheet in 1st row of the sheet. However if it is a new currency then the code should find last used cell in row 1 and add it. The value of Amount should be added to Output sheet against the currency and ID number also copied from the Source sheet.
I have some code.
Public Sub loopRow()
Dim curArray As Variant
Dim listarray As Variant
Dim cnt As Long
'Find Currency
Dim rgFound As Range
Set rgFound = Range("A:B").Find("Currency")
'Find last used row
curArray = Cells(rgFound.Address).End(xlUp).Row
'Transpose list of currecny from the row down from the word Currency that it has found
listarray = Application.Transpose(Cells(Rows, curArray).End(xlUp)).Row
For cnt = LBound(curArray) To UBound(curArray)
curArray(cnt) = curArray(cnt)
Next cnt
For cnt = LBound(curArray) To UBound(curArray)
'Debug.Print curArray(cnt)
'Copy and paste into Sheet under the correct curreny, if new currency then add this in row A
Next cnt
End Sub
Whilst you need to understand your question is unanswerable as is, I'll do my best to help.
The problem we have is not seeing the source sheet the way you do, as we can't see it at all. You say you have the word Currency in columns A or B or both, and an ID column somewhere, and Amount values everywhere. That's tricky source data. If as is more likely, the ID is in a specific column and the amounts are in a set of columns, then we'd have a chance.
Your question outlines the basic steps you'd want to take pretty well, so you're off to a good start.
However you can do all of the work without VBA, certainly if I'm right about the Source data. Create yourself a working sheet, or multiple working sheets. Definitely one to sort out the full list of currencies. Grab a copy of columns A and B (by formulae) and then have the working sheet go through line by line and use logic to build the list. Spreadsheets are great at this.
Once you have the list, use it as row headers on your Output sheet and use sumifs to get the values. I am not sure how the IDs would fit in, but if they were to be your row headings, then do the same as the above to get the list of unique ids and link them into your Output page in column A. Your sumifs can handle that.
That will hardly tell you all you need to know, but if you work it out you'll have learned a lot about Excel and when you need to go into VBA.
If you'd rather do it with VBA, break down each step until it works, and then go onto the next one.
And if you want more help, paste your data in here. Anonymise it first if you need to.

Search through Excel tabs

I am not very familiar with VBA programming, though I have written a few basic modules. I am having some difficulty in coding the following problem. I would appreciate if someone could show a basic solution.
Problem: I have 3 tabs in an Excel file, "Rack1", "Rack2" and "Rack3". They each have a column called "tag". The tag column contains a code, made up of numerals 0 to 9999 and one letter, A or B.
I want to look up the first "A" code in Rack1, then find the matching "B" code. If the B code is not in tab "Rack1", I want to search tab "Rack2", then "Rack3" if it's not found in either.
After the "B" part is found, I want to have a Msgbox message - "Found in Rack..." OR "B part not found"
Then ... go on to the next A code. Thanks
Please let us know what have you tried so far to get things working at your end.
You may have to loop through with your requirement with all sheets with respective column and its range.
I am not very clear, what is your exact requirement but you can do something like this
declare variables of your sheets
Set sheet1 = Worksheets("Sheet1")
Set sheet2 = Worksheets("Sheet2")
Set sheet3 = Worksheets("Sheet3")
You have to set range as per your need. Now you have to loop your sheet1 and tag column. While searching you need check whether A is exist in respective cell by cell value see below example
If InStr(cell_value, "A") > 0 Then
Meanwhile you can check below post for your further reference.
Excel Looping through rows and copy cell values to another worksheet

Anyway to have Find method start at the very firs cell ie A1

I have some really simple code that is looking for the first cell (Rng) to contain a certain string (FindString) cells in a range (A:A). Based on the data (which varies) sometimes this string is in the very first cell. The find function seems to search after the very first cell (A1). I can get around this by inserting a blank row at the top of my data but that seems like an ugly way to do it.
My code is simply:
Set Rng = Range("A:A").Find(FindString)
Thanks
Set the After parameter to the last cell of your range, see my answer here

Excel: Count same number values in noncontiguous range

I'm looking for the most elegant way to count the same number values in a noncontiguous range (I'll refer to it as just 'range'). This is the range:
=$C$2:$C$31,$E$2:$E$31,$G$2:$G$31,$I$2:$I$31,$K$2:$K$31,$M$2:$M$31,$O$2:$O$31,$Q$2:$Q$31,$S$2:$S$7
These are the parameters:
The range contains non-adjacent columns.
The columns differ in height.
The cells in the range are either empty or contain integers.
I'm checking for how many cells equal '1', how many equal '2' etc. in the range. (Not in one go, but in seperate formulas).
I've used a named range to reference the range. I'd really like to use this named range in the formula, in one way or another.
I hope I've given you enough info... Thanks in advance!
I agree with Kartik that a VBA solution is required. However the solution offered is a little inefficient in that it loops over every cell in the ranged passed into the function. It also limits the key parameter to a range reference, and can only count up to 32767 matches. Here's an alternative addresses these shortcomings
Function CountIf_N(rng As Range, key As Variant) As Variant
Dim r As Range
Dim count As Long
count = 0
For Each r In rng.Areas
count = count + WorksheetFunction.CountIfs(r, key)
Next
CountIf_N = count
End Function
Note: assumes Excel 07 or later. If using with an ealier version replace CountIfs with CountIf
One approach is to use excel built in function Countif, but it won't work with non-contigous range. The other way (the easy way) will be to use VBA to create your own custom function, and then use it in excel.
I've presented that technique here.
Goto visual basic editor in excel by pressing Alt+F11, in the project window insert a new module and paste the below code:
Function countif_n(rng As Range, key As Range) As Integer
Dim count As Integer
count = 0
For Each cell In rng
If cell.Value = key.Value Then
count = count + 1
End If
Next cell
countif_n = count
End Function
Here rng is your non-contigous range, and key represent the "range"(cell) which contains the value you want to count. For eg., to check for 1 enter 1 in any cell lets suppose "F2", and your non-contigous range is "testrange"
Then use the above function by entering the following in any blank cell:
=countif_n(testrange, F2)
Although COUNTIF can't handle non-contiguous ranges some functions can, for example RANK and COUNT so for a range called Range this formula will give the number of instances of a number in Z2 within Range
=IFERROR(COUNT(Range)-SUM(RANK(Z2,Range,{1,0}))+2,0)
assumes Excel 2007 or later but can be amended to work in earlier versions
This doesn't quite work if there's stuff below S7 that can't be counted, but you may be able to modify. It also doesn't incorporate the named range.
=SUM(IF(MOD(COLUMN(A2:S31),2)=0,IF(A2:S31=2,1,0)))
This example counts the number of 2's.
This needs to be array-entered with ctrl-shift-enter. It's based on the fact that you're counting in every other column, at least in your example. Also, although you mention the columns are different heights, it looks like all except S are the same height. So maybe there's a way to work around that.

Resources