VBA formula for cell in excel, inserting special character ambiguously [duplicate] - vba

I am adding a formula to a worksheet via VBA which should be:
=UNIQUE(IF(TableA[ColumnA]=A1,TableA[ColumnB],""))
This utilises the new SPILL feature in Excel to give me a list of column B values where the related value in column A matches what is in cell A. I'm also applying the UNIQUE function to remove any multiple blank ("") results.
This works perfectly if I manually type the formula into Excel, however in using VBA to add the formula, Excel is adding # symbols within the formula, and causing it to show #VALUE!.
The VBA line being used to add the formula is:
=Cells(x,y).Formula = "=UNIQUE(IF(TableA[ColumnA]=A1,TableA[ColumnB],""""))"
The resulting output in Excel is:
=#UNIQUE(IF(TableA[#[ColumnA]]=A1,TableA[ColumnB],""))
What is going on, and what have I missed?
Thanks in advance!

Good question, and I looked it up...
In short:
Use =Cells(x,y).Formula2 instead of =Cells(x,y).Formula
Explaination:
The # that shows is called the implicit intersection operator. From MS docs:
Implicit intersection logic reduces many values to a single value. Excel did this to force a formula to return a single value, since a
cell could only contain a single value. If your formula was returning
a single value, then implicit intersection did nothing (even though it
was technically being done in the background).
But why does it appear in your newer Excel O365? Well, Range.Formula uses IIE (implicit intersection) thus adding the # to basically undo your dynamic array functionality. UNIQUE is a new dynamic array function. So, to write this out in code, you should use the Range.Formula2 property (or Range.Formula2R1C1 if you use R1C1 notation). These properties use AE (array evaluation) and is now the default.
Here is an informative doc from MS on the subject which explains the difference between Formula and Formula2 in more detail.
If you want to know more about the implicit intersection operator then have a look at this
I answered another question earlier on that involved implicit intersection with an example on how that actually works here if one finds it interesting.

Related

Vba Function that counts how many times a text is contained inside a string?

I have a very specific question
There is a native vba function that counts how many time a text (such as a word or even a single character) repeats inside other text (string)?
It would get as parameters two string values, for example, and return a integer/long value.
I looked among worksheet functions and I couldn't find any. Should I make my own one?
Thanks very much!
As it doesn't exist in vba, you should make your own. You can write a loop using InStr, counting the number of iterations. It should be pretty performant as it essentially won't have to do any memory allocations, and VBA's string functions are fast.

vba Excel to Access: zero length string to Null number

I have two values in the same column in Excel. I select one of them and run the following:
Debug.Print IsNumeric(Selection), _
VarType(Selection), _
VarType(Trim(Selection)), _
">" & Selection.Value & "<", _
Len(Trim(Selection)), _
Len(Selection), _
Selection.NumberFormat
Then I select the other and run the same debug.
And I get this:
True, 5, 8, >9.46979663546499<, 16, 16, General
False, 8, 8, ><, 0, 0, General
Note: the column has multiple occurrences of both
Can someone explain this? I've been vba'ing and Excel'ing a long time and I still don't get (in detail) the number formatting Excel does and how to work with them best. I think I have it then I always stumble upon something new like this.
In this case my objective is to get MS Access to automatically understand that this column is a double/number/float/whatever column that can be NULL when I import it and not throw errors. I have to achieve this through formatting/changing it in Excel prior to importing it. (Partly because that will work best with my client's processes and partly because I want to get my head around this finally...can't believe I don't already!) I have over 2000 rows to change for each column so a solution that formats the entire column at once would be best, not just one cell at a time.
Thanks!
IsNumeric returns true for the number and false for the blank. I'm not sure if this is unexpected, but MS had to make it return one or the other. The logic is that a blank is neither numeric or text.
Vartype returns Double for the number (as expected). If I VarType an empty cell, I get vbEmpty (0), not 8 as you get (Excel 2010 x86). If I put a single apostrophe in the cell, I get the same as you.
When you Trim() something, you convert it to text. It doesn't matter what you trim, the Trim function only returns a string, so you will always get VarType 8.
Read this post on mixed data types http://dailydoseofexcel.com/archives/2004/06/03/external-data-mixed-data-types/. Make sure you read the comments.
When an Office program imports, it uses some registry keys to determine data types. Typically, it reads the first 8 rows of the field to determine what the data type is. If it sees a mixture of data types, it picks the majority and converts or ignores everything else. You can change the registry settings to look at more than 8 rows or to default everything to text, but you can't tell it to treat empty cells as numbers.
It would be nice if it would simply ignore empty cells and take the majority of the rest. But 'empty cell' is just not a concept outside of Excel so it doesn't really surprise me.
The right answer for you, I think, is to create a Schema file and put it in the same directory as the file you're going to import. Read about it at https://msdn.microsoft.com/en-us/library/ms709353%28v=vs.85%29.aspx This is essentially setting all your column data types in a file.
I use this almost every day in Excel VBA - I use VBA to create a Schema.ini file, then use ADO to read in the file. I haven't ever used this in Access, particularly importing through the UI. But it's worth a try. If it doesn't work, you can just do all the importing yourself in VBA and ADO.
First, I would look logically at what type of data each column SHOULD contain. Some numbers are not to be calculated and therefore should be treated as text, especially in the case of (for example) item numbers with leading zeroes. You definitely DO NOT want to convert those to numbers and lose those leading zeroes, it will typically lead to downstream issues if whatever is querying them can't handle implicit conversion. Another example of this is where numbers exceed 15 in length. Excel will turn everything after the 15th digit to a zero because it's not a significant figure, but if this is a serial number (or the like) you are corrupting the data.
Once you understand what each column should be, use text-to-columns. Numbers should be general, dates should be dates, everything else should be text.
http://www.excel-easy.com/examples/text-to-columns.html
Text-To-Columns is superior for this purpose because it will actually convert the data type. If you use formatting it doesn't apply the formatting until you edit the cell.

AutoSum and Sum return '0' when trying to add numbers imported by SQL

Excel 2007 - anytime I click AutoSum it shows 0, or anytime I use the formula to Sum it still gives me a 0.
This is a SQL Query that is imported by using Data-Connection-SQL Server and saved SQL Query in the workbook.
What gives that is keeping me from totalling?
It seems to me the most likely explanation is that what you are trying to add are strings. If so, with Error Checking activated (Formulas tab) little triangles (by default green) should be clear evidence.
These also provide an easy way to convert strings that look like numbers into numbers that Excel can add. Select a contiguous range starting with a cell requiring conversion and a warning sign should appear:
(not always top left). Click on the exclamation mark and on Convert to Number and hopefully the format of all cells in your selection will be converted so your SUM function behave as you would like.
Much less likely (because I don't see how you would have done) is that somehow you have acquired leading spaces and when entering data it was into a cell formatted as Text. The triangle warning would be the same but Number Stored as Text does no conversion. A formula such as:
=TRIM(A1)
should do however, though it does depend on the type of space (eg would not work for NBSP - though you should not acquire one of those from an SQL import).
There may be other possible causes but it seems best to try the above before alternatives.

Quickly Convert Text To Numbers or Dates Excel VBA

Is there any way to QUICKLY convert numbers/dates stored as text (without knowing exactly which cells are affected) to their correct type using VBA.
I get data in an ugly text-deliminated format, and I wrote a macro that basically does text-to-columns on it, but is more robust (regular text-to-columns will not work on my data, and I also don't want to waste time going through the wizard every time...). But, since I have to use arrays to process the data efficiently, everything gets stored as a String (and is thus transferred to the worksheet as text).
I don't want to have to cycle through every cell, as this takes a LONG time (these are huge data files - I need to use arrays to process them). Is there a simple command I can apply to the entire range to do this?
Thanks!
This has to do with the data type of the columns modify the column from general to the correct data type and the placement of text data should get automatically converted... here's an example where I pasted the text 012345 into different columns having different data types. Note how the displayed value is different for the different types but the value is retained (except on number and general which truncate a leading 0.
However if you don't know what field is of what type... you're really out of luck.
There is a way is there. Just multiply 1 with the data in the column have text to converted as number, whether it is text or not it will convert to numbers only.
Read the following the link for more.
http://chandoo.org/wp/2014/09/02/convert-numbers-stored-as-text-tip/

Excel 2007 (Conditional Formatting) AND & IF

I hope you can help me on this issue.
I am currently using Excel 2007 and I am creating a dynamic Planning/Time Sheet for our Team.
So far everything is going well.
Now unfortunately I am having an issue with the Conditional Format.
I am formatting the Cells in order to graphically show the current Status of the Person working. I am using the Conditional Format with a Formula example: =OFFSET(DataStart17D;COLUMN();ROW()-49;1;1)="PM"
Now I am trying to applying 2 conditions with a gradient fill of 2 colors like example: =AND(IF(OFFSET(DataStart17D;COLUMN();ROW()-49;1;1)="PM";TRUE;FALSE);IF(OFFSET(DataStart17D;COLUMN();ROW()-52;1;1)="AM";TRUE;FALSE)
Problem is, as soon as I use the IF or the AND Statement no condition is applied at all.
I have applied the above formula to the Cell itself and have received "TRUE" as the condition.
What is odd too is that if I apply =OFFSET(DataStart17D;COLUMN();ROW()-49;1;1)="PM" it works fine, if I use =IF(OFFSET(DataStart17D;COLUMN();ROW()-49;1;1)="PM";TRUE;FALSE) once again no condition applies.
I have searched the web for a Solution and could not find one yet :(
Would really be pleased if someone could help me on this one :)
Best Regards,
Richard J. Dana
You don't need IF Statment and TRUEs and FALSEs withih a Conditional Formatting formula. By its nature the formula is conditional.
Try something like:
=AND(OFFSET(DataStart17D;COLUMN();ROW()-49;1;1)="PM";OFFSET(DataStart17D;COLUMN();ROW()-49;1;1)="AM")
Once you do so, you'll see an additional problem. The two statements in your AND function are mutually exclusive, so it will never evaluate to TRUE.
EDIT:
There does seem to be an issue with the AND statement and multiple OFFSET statements that use ROW or COLUMN
Please note that I'm going to use commas instead of semicolons as function parameter separators here, otherwise it's too hard to convert. You'll have to change the commas back to semicolons.
Also note that you didn't need the last two arguments in either the ROW or COLUMN function in your original question. You had them set to a height and width of 1, which is the default, and is optional.
Here's a simplified example:
If you do something like:
OFFSET(DataStart17D,ROW()+1,COLUMNS())="PM"
it will evaluate to TRUE in the worksheet and also in the conditional formatting
If you do something like:
=AND(OFFSET(DataStart17D,ROW()+1,COLUMNS())="PM",OFFSET(DataStart17D,ROW()+1,COLUMNS())="PM")
which is just repeating the same statement twice, it will evaluate to TRUE in the worksheet, but won't trigger the conditional format.
All of the above is just as you stated in your question. The answer that I think works is to use ROWS and COLUMNS instead, like this:
=AND(OFFSET(DataStart17D,ROWS($1:2)+1,COLUMNS($A:A))="PM",OFFSET(DataStart17D,ROWS($1:2)+1,COLUMNS($A:A))="AM")
The above would be the formula for A2. Note that the first row or column inside the parentheses is anchored with a dollar sign. This gives you the count of rows or columns from A1, effectively the same thing as the ROW or COLUMN function.