MATCH function suddenly stopped working - excel

I wrote this VBA macro for Excel code many years ago and it has suddenly stopped working. I'm trying to find the row index in one sheet that exactly matches an entry in the current sheet. The line of code that has stopped working is:
Cells(rr, cc + 1).Value = "=MATCH(RC[-1], Num, 0)"
I'm not sure what Num is, since it isn't referenced anywhere in the macro earlier. In particular, I don't see how it references the worksheet i'm interested in.

If you were trying to put a formula into the cell defined by row:=rr, column:=cc+1 then the code really should be,
Cells(rr, cc + 1).FORMULAR1C1 = "=MATCH(RC[-1], Num, 0)"
(sorry - all caps for emphasis) That formula would make use of a Named Range called Num. Check Formulas ► Defined Names ► Name Manager for its existence. It will refer to a single row or column of cells where the lookup for the value of one cell to the left is performed.
If you try and put an xlR1C1 style formula in as the .Value, it may be correctly interpreted by the worksheet overhead as a formula. However, without a defined Num range, this would produce the #NAME? error on the worksheet.

The problem turned out to be a bad data entry in the worksheet I was trying to MATCH to. I don't know why it didn't just return a FALSE value. However, I have solved my problem thanks to the help from this site.
Thanks.

Related

Inserted formula with cell reference does not recognize new input

I swear this just worked yesterday...
I have a program that creates formulas within certain cells that depend on subsequent data entries into other cells:
Cells(i, 40).Formula = "= (N" & i & ")/AP" & i
So, APi can be input and/or changed after the fact, and the formula should give you the result for whatever value is there. However, I get a #Div/0! error no matter what value is in that cell. When I evaluate the formula (within Excel) and step through the calculations, it shows this (for one particular cell):
= (N64)/AP64 = (47.35)/AP64 = 47.35/AP64 = 47.35/9 = #DIV/0!
So, the formula recognizes that there is a value in the cell AP64, but then does not use it to properly calculate the result.
As I said at the top, this worked as I expected yesterday afternoon when I was testing it. Now that I need other people to start using it, of course, it doesn't. I changed nothing within the program relative to these lines of code.
I apologize if this is answered elsewhere - I really have no idea how to create a search for this type of problem.
Two things to check:
1) Value of the cells used is formatted to a number (i've had #Value based on that a couple times) and
2) verify that modifying the code using fixed references provides the appropriate output ("A16" for some reason wasn't recognized as a cell reference in one I had show up). E.g., "$N" & i & "/$AP" & i
If those both look alright, you might try something like:
.Range(.Cells(3,40),.Cells(lr,40)).Formula = "=$N3/$AP3" 'ensure no random spaces
This should act like a fill-down in which the # 3 is iterated with the same row as the formula.

How to use relative names in Excel VBA

Many "advanced" (aka: VBA) excel tutorials on the web or even excel's vba help encurage us to use the
Range("B2:B10")
method (to be precise: object) for selecting cells or getting values. In the same place they often add it's totally ok to use predefined names as well:
Range("valuesabove")
On the other hand I fell in love with the incredible power of relatively defined cell names. They make it so much easier to write and handle big composite formulas, and basically to refer to nearly anything.
However, relative names don't work in the Range("valuesabove") method the way we are used to it.
Usually (when used on the worksheet) relative names are relative to the currently selected cell or to the cell in which they are used.
In VBA's Range() object this is not true. Range is relative to a WorkSheet object, by default to the ActiveSheet. But ActiveSheet is represenetd by its leftupper cell, A1. And this is what Range turns out to be relative to. And this is why absolute names ($C$23) do work with it, and relative ones ("one column to the left, two rows up") don't.
So my question is:
How can I harness the power of relative names in VBA then?
EDIT:
Realising that my question was rather unclear (thx's go to you guys commenting tirelessly) let me try to put it in a specific form and clarify terms:
IMHO on an excel worksheet it is very comfortable to use names in order to refer to cells or define calculated values by functions based on cell values.
In excel a reference to a cell can be either relative, absolute, or mixed. This is true also when creating names. Thus we can speak about absolute, relative or mixed names (in terms of referring of course).
Here an absolute name is used a couple times (created using excel's Trace Dependents function):
Name "name" = $D$2
A relative name is used a couple times here:
Name "upright24" while, e.g. cell A7 is selected = C3 (without $ signs!). But this changes constantly according to the selected cell or region. You can check it in the name manager! (Ctrl+F3)
And this is what we can consider as a mixed name:
Name "rel_serialnumber" while, e.g. cell C6 is selected = $B6. The row of which (6) changes constantly according to the selected cell or region.
The creation of a relative or a mixed name is explicitly based on the active cell at the moment of creating the name. The creation of an absolute name naturally doesn't rely on the cursor position.
Note, that
absolute names mean a dinamic offset from the referenced cell, which is one and only
relative names mean a static offset from the referenced cell, which thus changes always corresponding to the place where the name is used
mixed names mean a mixed (or half-dynamic) offset from the referenced cell, the row or column of which thus changes always corresponding to the place where the name is used while the other remains always the same (the offset in one or the other direction remains zero).
Okay, now here is the thing. I have a database-like excel sheet where I handle the rows like records and the columns as fields for properties. The user uses this thing as follows: he "selects a record" by placing the cursor in any cell of the row of the desired record. Then he presses a big command button which starts my VBA macro. This intends to open a prepared skeleton file and fill some specific cells in it (which are btw defined by absolute names) with some values (which are defined by mixed names) from the selected record.
Since Range("name") is considered ok to use in VBA (see above) I thought Range("relativename") or Range("mixedname") will work just as fine while automatically relying on the active cell.
I couldn't be worse.
Only Range("absolutename") works in the way one would expect! Explanation see above.
So I'm after a function / method / object that is possibly as comfortable to use with a "relativename" or a "mixedname" as Range("absolutename") is.
It appears you are looking for Range.Offset() http://msdn.microsoft.com/en-us/library/office/ff840060%28v=office.15%29.aspx
However you could do it as:
'Your example Range(Col_B_in_current_row) as
Range("B" & ActiveCell.Row).Select
'Your example Range("B2:B10") -> Range("valuesabove") as
Range("B2:B10").Offset(-1, 0).Select
Just seems like a relatively simple syntax already exists for this.
I think I've found a proper and compact solution. It's
Names("mixedname").RefersToRange
Not as short as Range("mixedname") would be but it is really providing the expected values.
UPDATE:
This solution is mostly unuseful if you want to copy relative-named cell values in a source workbook to relative-named cells in a dest workbook with a single codeline. This is because Names() relies on the actual position of the cursor which is depending on which workbook is currently the active one and in most cases this won't be ok for the other.
In this case the non-fixed part of the name has to be stored:
sourcerow = ActiveCell.Row
[...]
'opening a wbk, this also makes it the active one
[...]
Names("dest").RefersToRange = mysheet.Cells(sourcerow, mybook.Names("src").RefersToRange.Column)
To reference a Range relative to another Range you can use this syntax:
myRange.Range("namedRange")
Note: This only works if both the Row offset AND the Column offsets are positive. For example if the "Refers to" formula for the named range is "=Offset(A1,r,c)", then the above syntax will throw an error if Either r Or c is negative. But, it will work if both are positive.
The asymmetry is unfortunate but business as usual for VBA...
To Reference the third column in the row of the current ActiveCell:
ActiveCell.EntireRow.Range("C1")
To reference a cell offset by (for example) 1 row and 3 columns relative to the ActiveCell:
ActiveCell.Range("C2")
Obviously, you can use the same syntax with the Selection Object or any other Range value in VBA.
Private Sub Worksheet_Change(ByVal Target as Range)
If Not Intersect(Target.Address,ThisWorkbook.Sheets('sheetname).Range('RangeName)) Is Nothing Then _
'Do whatever you want down here.
ThisWorbook.Sheets('sheetname).Range('RangeName).Offset(0,Target.Row)
End If
End Sub
This should send you on the right path to what you want (which is super unclear). Use the worksheet change event to bring in user worksheet selections and changes into VBA modules. Put it into the relevant sheet.
I had the same problem, but I did get it to work - sort of. I don't know what is different about the simple example below, but it works. At first I thought selection mattered, but no - it works without changing the active cell.
(I still can't get it to work in my main spreadsheet.)
Named range: "TestName" = Sheet1!$H1
Values in H1:H10 = 1,2,3,4,5,6,7,8,9,10
Sub Test()
Dim x As Integer
For x = 0 To 10
Range("A1").Offset(x, 0).Value = Range("A1").Offset(x, 0).Range("Testname").Value
Next x
End Sub
Result: A1:A10 = 1,2,3,4,5,6,7,8,9,10

VBA - Sum Cells with the 'Number Stored as Text' error

In Excel 2010, I am writing VBA to take the SUM of a range of filtered values, and store that result into a variable. The code looks like this:
With Sheets("Output")
.Range("$A:$ZZ").AutoFilter field:=ColIndex(AB), Criteria1:="x"
y = Application.WorksheetFunction.Sum( _
Range(Cells(2, "AC"), Cells(10, "AC")).SpecialCells(xlCellTypeVisible) _
)
This does work, but only when I have manually toyed with the data. When I try to use this formula on my data set unedited, I get a blank result. The problem seems to lie with the data when unedited.
Each number gets the Number Stored as Text (NSaT) error. Changing the type from Text to General causes nothing to happen. I have to open the cell for editing, and then remove focus from the cell for the type to kick in. After that, I can change it back and forth from General to Text, and Excel immediately recognizes this and updates the cell. The Sum function will, at this point, recognize both General and Text field types as a number.
Is there a VBA solution for dealing with these NSaT errors? I have attempted to use 'NumberFormat' on the column, but it does not help. I have also tried manually copying and pasting the data again, even using the special As Value option, but it still has the NSaT error until manually toyed with.

VBA eats my zeros INSIDE a string?

So here is a problem that I have never come across before. I Import an ISIN (for example DE0002635307) from a cell, which is defined as a text. I need to use this to reference to a cell by that name. So:
sub ISINWriter
dim ISIN as String
ISIN = ThisWorkbook.Sheets(i).Cells(j, 4).Value()
ThisWorkbook.Sheets(i+1).Cells(f, 4).Formula = "=" & ISIN
End Sub
For most of the ISINs this works fine, except if there are 4 or more zeros in a row. If that happens - for example FR0000120073 - it writes "=FR120073" into the cell. It just eats the zeros INSIDE the string! Any ideas?
I use Excel 2010 and Windows 7.
Thanks a lot.
If you use the Name Manager to try to create a named range (or more accurately a named formula) called "FR0000120073" then you should find that you get an error. Something like (from Excel 2007 on my machine):
The name that you entered is not valid.
Reasons for this can include:
- The name does not begin with a letter or an underscore
- The name contains a space or other invalid characters
- The name conflicts with an Excel built-in name or the name of another object in the workbook
The clue is in the last part of the third reason. FR120073 is a valid cell address in these days of 16Kx1m cell worksheets.
The first reason above may be useful, though: _FR0000120073 is a valid name. Could you use that?
EDIT: Removing my last answer so this makes sense.
Basically your cell references are an AlphaNumeric value. Take A1 for example A is the column 1 is the row. This issue is occuring because 0001 is the same as 1. so a reference to cell A001 is going to be the same as cell A1.
It looks like Excel has some built in functionality to remove leading 0's from your references to cells.

Excel VBA Calculate Method not update Array Formulas; showing as #N/A

I have a series of array formulas in Excel that key off of each other. These are automatically resized to fit a range of data that is generated via a proprietary Excel add-in.
However, whenever my code rewrites some of the array formulas to the correct new size, the cells all show as #N/A until either you edit another unrelated cell on the sheet, save the sheet, or press F9.
Using code such as Application.Calculate, ActiveSheet.Calculate, etc do not have any effect.
However, using SendKeys "{F9}" does.
As an example, these are two formulas on the sheet:
={IF(LEN(INDEX(A:A, ROW()))>0,ROW(A:A)+2)}
and
={LARGE(OFFSET($J$1,0,0,ROW()),1)}
The first formula works fine after writing it programmatically to a range of cells. It merely tells me the row number of a cell that has text in it.
The second formula does not work after writing it programmatically to a range of cells. It gives me the largest row number that has been previously seen in a list of numbers (which is the output of the first formula). If I press F9, the second formula updates correctly. If I do Application.Calculate in VBA, nothing happens. I've also tried the various other recalculate methods available at the Worksheet level as well, but no luck.
Has anyone encountered something like this before?
edit:
The resize code essentially boils down to something like this (stripping out all of the support code that allows me to make more generalized calls to it):
First, I do:
formula = dataSheet.Cells(startRow, startColumn).formula
Then later:
Set DeleteRange = dataSheet.Range(dataSheet.Cells(startRow, startColumn), dataSheet.Cells(bottomBound, rightBound))
DeleteRange.ClearContents
Set DeleteRange = Nothing
Then later on:
Set resultRange = dataSheet.Range(dataSheet.Cells(startRow, startColumn), dataSheet.Cells(startRow + Height - 1, startColumn + Width - 1))
resultRange.FormulaArray = formula
Set resultRange = Nothing
In a nut shell, I make a copy of the formula, clear the range, then rewrite it.
If you can't beat 'em, join 'em.
SendKeys "{F9}"
I have fleshed out my comment above given you have implemented this approach
using this code
Dim strFormula As String
strFormula = "=LARGE(OFFSET($J$1,0,0,ROW()),1)"
Range("a1:a5").FormulaArray = strFormula
xl03 gives numbers but needs a calc to update the cells properly
xl07 gives the "#N/A" (and raises a Calculate in the statusbar)
xl10 works fine
As you point out none of the calculation options including a full dependency tree rebuild work
using my RAND suggestion above does force the update in xl07
Dim strFormula As String
strFormula = "=LARGE(OFFSET($J$1,0,0,ROW()),1)+ RAND()*0"
Range("a1:a5").FormulaArray = strFormula
OFFSET is a volatile function see Voltatile Excel Functions (which includes a file that tests volatility)
Perhaps Charles Williams can shed some light on this, I will ping him
Looks like a FormulaArray bug in 2003 and 2007.
A simpler bypass for your formula would be to use Range("a1:A5").Formula instead of formula array since =LARGE(OFFSET($J$1,0,0,ROW()),1) does not need to be an array formula
My recollection is that there is also an Application.CalculateFull method - does that work?
My cells were not refreshing after ranges they depended on were modified either.
I also had to hand edit each one to get them to re-calculate.
SOLUTION:
Use fully qualified references within your formulas.
e.g. any formulas that look like this YourFunction(G200:H700) should be changed to look like this YourFunction('Your Sheet Name'!G200:H700).
Auto-Refresh now works perfectly for me.

Resources