Following up on an earlier question I had about horizontal vs vertical arrays, I have a question about it's respective delimiters.
Problem definition:
Hereby an example of an incorrect way of comparing two arrays:
{=SUMPRODUCT(--({"Apple","Pear"}={"Apple","Lemon","Pear"}))}
The correct way, in case of an English application countrycode would be:
{=SUMPRODUCT(--({"Apple","Pear"}={"Apple";"Lemon";"Pear"}))}
Within an English version (most likely more than just English) of Excel these delimiters would respectively be a comma , for horizontal arrays and a semicolon ; for vertical ones. Plenty of online information to be found on this.
Working on a machine with a Dutch country code on it's application however, it't a complete other story. It does frustrate that my delimiters would both be different, respectively ; and a \. Being able to rather simply retrieve the semi-colon it's proven to be tricky to find any documentation on these delimiters for international version.
Workaround:
Not knowing these delimiters up-front makes it tricky for anyone on a variety of international versions of the application to work with these type of formulas. A rather easy workaround would be to use TRANSPOSE():
{=SUMPRODUCT(--({"Apple";"Pear"}=TRANSPOSE({"Apple";"Lemon";"Pear"})))}
Going through the build-in evaluation we can then retrieve the backslash as the column seperator. Another way would be to use the Application.International property and it's xlColumnSeparator and xlRowSeparator.
Question
We can both find and even override the xlDecimalSeparator and xlThousandsSeparator through Excel (File > Options > Advanced), or VBA (Application.DecimalSeparator = "-") but where can we find:
A place to actually see which xlRowSeparator and xlColumnSeparator are used within your own application, other than the workarounds I described. Looking for an interface similar to thousands and decimal seperator and/or official MS-documentation.
Furthermore (not specifically looking for this), is there:
A place to override them just like the decimal and thousand seperators
If not through Excel interfaces, can we brute-force this somehow through VBA?
I'm very curious if official documentation is present, and/or if the above can be done.
Not claiming this is the right answer, but with the help from comments from other users, maybe the below can clarify things a bit:
With no sign of any official documentation on this matter, and seemingly random row and column delimiters #Gserg showed a trick to retrieve information for any LCID using these unique id's on MS office support under "Create one-dimensional and two-dimensional constants". While this is MS office support information, the delimiters you see there are FALSE. They might come up as . a , a ; a : a \ or even a |. You get this results by changing the LCID from the URL to a LCID of interest, e.g.: fr-fr.
Although there are about 600 different LCID's they all get redirected to a default LCID. With the help of #FlorentB. we discovered that not only the MS office support documentation is wrong, it seems that these delimiters are not that random after all. Looking at countries using a decimal point, they use the , as a column delimiter (a horizontal array) and a ; as a row delimiter (a vertical array). Countries using a decimal comma however use a \ as a column delimiter and a ; for rows respectively.
Changing the system country settings, checking all default LCID's in Excel, we ended up with the matrix below showing all row and column delimiters per default LCID:
| LCID | Row | Column |
|-------|-----|--------|
| ar-sa | ; | , |
| bg-bg | ; | \ |
| cs-cz | ; | \ |
| da-dk | ; | \ |
| de-de | ; | \ |
| el-gr | ; | \ |
| en-gb | ; | , |
| en-ie | ; | , |
| en-us | ; | , |
| es-es | ; | \ |
| et-ee | ; | \ |
| fi-fi | ; | \ |
| fr-fr | ; | \ |
| he-il | ; | , |
| hr-hr | ; | \ |
| hu-hu | ; | \ |
| id-id | ; | \ |
| it-it | ; | \ |
| ja-jp | ; | , |
| ko-kr | ; | , |
| lt-lt | ; | \ |
| lv-lv | ; | \ |
| nb-no | ; | \ |
| nl-nl | ; | \ |
| pl-pl | ; | \ |
| pt-br | ; | \ |
| pt-pt | ; | \ |
| ro-ro | ; | \ |
| ru-ru | ; | \ |
| sk-sk | ; | \ |
| sl-si | ; | \ |
| sv-se | ; | \ |
| th-th | ; | , |
| tr-tr | ; | \ |
| uk-ua | ; | \ |
| vi-vn | ; | \ |
| zh-cn | ; | , |
| zh-hk | ; | , |
| zh-tw | ; | , |
The apparent conclusion is that all countries use a semicolon as a row (vertical) delimiter. And depending on decimal seperator countries use a backslash or comma as a column (horizontal) delimiter within array formulas.
So even without proper MS-documentation, nor a place within the Excel interface (like thousand en decimal delimiter do have), on this matter it is apparent that knowing your country's decimal seperator will automatically mean you either use a \ or , as a column delimiter.
| Dec_Seperator | Row | Column |
|---------------|-----|--------|
| . | ; | , |
| , | ; | \ |
I would happily recieve more information about the above and/or presence of any correct MS office documentation to add to this.
It is possible to do this through native Excel (without VBA or add-ins) by querying Excel's C API, but I don't know of anywhere this is documented.
Go into Excel's Name Manager and click 'New...'. Enter a name such as GetColumnSeparator.
In the 'RefersTo:' box, enter the following to get the column separator:
=INDEX(GET.WORKSPACE(37), 14)
In an Excel cell, you can now enter this:
=GetColumnSeparator
and the comma (in English - or whatever symbol is in use on your machine) will be shown.
For the row separator you need to change the index number to 15:
=INDEX(GET.WORKSPACE(37), 15)
On an English machine, this will be the semicolon by default.
On machines where Excel's 'display language' is not English (meaning Excel's function names are translated), you will need a translated version of the above formula. Again I don't know of any documentation on this, so my best suggestion would be to install the English language pack, enter the formula in English, save the workbook, then revert to your original Excel language and re-open the workbook; Excel will translate the formula automatically.
Note that you will need to save the workbook as macro-enabled (e.g. .xlsm rather than .xlsx).
Sorry this is nearly three years late but I hope it helps.
Related
I have a set of data within a spreadsheet that need to filter with specific parameters. I need to return data that matches the final 3 characters of a 6 character string.
For example if I have the following data:
| Col 1 |
---------
| AA-XYZ |
| AA-ABC |
| BB-XYZ |
| BB-DEF |
| CC-XYZ |
| CC-GHI |
My filter would return:
| Col 1 |
---------
| AA-XYZ |
| BB-XYZ |
| CC-XYZ |
Is this possible with a standard search/filter function or would a regular expression be required?
=FILTER(A3:A8,RIGHT(A3:A8,3)="XYZ") or if you want to enter the filter in a cell =FILTER(A3:A8,RIGHT(A3:A8,3)=C1)
Try below formula-
=FILTER(A1:A,INDEX(COUNTIFS(INDEX(SPLIT(A1:A,"-"),,2),INDEX(SPLIT(A1:A,"-"),,2)))>1)
Consider a spreadsheet with a "source" spreadsheet and a "formatted" sheet
The formatted sheet references data from a source sheet.
The ideal way for this to work is to use array formula
# formatted-sheet (formulas)
| title | description |
------------------------
| = ArrayFormula(source!A2:AA) | |
| | |
| | |
# source (raw data)
| title | description |
------------------------
| SomeTitle | long description |
| OtherTitle | Other description |
| emptyDesc | |
In google spreadsheet, the resulting formatted sheet displays like this :
# formatted-sheet (rendering formulas)
| title | description |
------------------------
| SomeTitle | long description |
| OtherTitle | Other description |
| emptyDesc | |
However after exporting to Excel format, the empty values are displayed as "0"
# formatted-sheet (rendering formulas)
| title | description |
------------------------
| SomeTitle | long description |
| OtherTitle | Other description |
| emptyDesc | 0 |
| 0 | 0 | # for every additional line captures by the array formula, zeroes everywhere
The fix I found for this, is to use an IF to check for empty string values
# formatted-sheet (formulas)
| title | description |
------------------------
| = ArrayFormula(IF(source!A2:AA = ""; ""; source!A2:AA)) | |
| | |
However the IF() formula is broken for cells that are longer than 255 characters, Is there a different workaround possible ?
Foe example a way to rpevent the empty strings to appear as "0" after exporting to xlsx and opening with Microsoft Excel ? or to improve the formula ?
Here is the reference for a sample sheet.
Try using:
=ARRAYFORMULA(IF(NOT(ISBLANK(source!B2:B)),source!A2:AA,""))
it also hides the last "emptyDesc". If this is not your intention please let me know.
I found out this trick from this question that is quite concise to convert everything to a text like format.
=ArrayFormula(source!A2:AA & "")
However it will most likely kill the formatting of numbers and interoperability, I have not made extensive tests regarding this, as it is fine for me in the current state
I am trying to do a SUMIFS in an Excel sheet where I need to take into consideration cells that are filtered. I can accomplish this with a pivot table, but the same source data is already being using in a handful of Bubble Charts which update on filtering anyways. The only reason for this other table to the data needs to be aggregated differently to get the desired chart out. I am trying to avoid Pivots so that once the user selects their filters in the Source Table (using Slicers) the destination table and accompanying chart just update. If I use a pivot table to handle this part the user will have to duplicate work by putting their parameters into the Slicers and the PivotTable.
Row# in the real data is a unique identifier for each row. For filtering there is roughly 20 columns that could be filtered.
I have seen that SUMPRODUCT can do this, but I cannot wrap my head around how to do it with my data set.
Source Table Example
+------+---------------+-------+-------+-------+---------+----------+
| Row# | Amount | Class |Channel| Other | Columns | ToFilter |
+------+---------------+-------+-------+-------+---------+----------+
| 1 | $122,616.16 | 10 | A | Stuff | Stuff | Stuff |
| 2 | $128,587.43 | 1 | B | Stuff | Stuff | Stuff |
| 3 | $273,055.04 | 10 | C | Stuff | Stuff | Stuff |
| 25 | $144,087.59 | 4 | A | Stuff | Stuff | Stuff |
| 26 | $273,537.45 | 2 | A | Stuff | Stuff | Stuff |
| 27 | $110,177.94 | 2 | B | Stuff | Stuff | Stuff |
| 3674 | $455,133.20 | 2 | C | Stuff | Stuff | Stuff |
+------+---------------+-------+-------+-------+---------+----------+
Destination Table Example
+---------+---------------+---------------+--------+---------------+-----+---------------+
| Channel | 1 | 2 | 3 | 4 | ~ | 10 |
+---------+---------------+---------------+--------+---------------+-----+---------------+
| A | $- | $273,537.45 | $- | $144,087.59 | ~ | $122,616.16 |
| B | $128,587.43 | $110,177.94 | $- | $- | ~ | $- |
| C | $- | $455,133.20 | $- | $- | ~ | $273,055.04 |
+---------+---------------+---------------+--------+---------------+-----+---------------+
Assuming the source table is located at A1:G8, and the destination table is located at A10:K13 .
Put '=IFERROR(INDEX($C$2:$C$8,MATCH(1,INDEX((B$10=$D$2:$D$8)*($A11=$E$2:$E$8),0,1),0)),"-")` in B11 and drag till the end.
Idea : use multiple criteria index match & wrap it in iferror(). $ is used to lock the reference column/row.
Ref : https://exceljet.net/formula/index-and-match-with-multiple-criteria
Please share if it works/not. ( :
I have a large list of users with various codes. The goal is to separate the good from the bad. All codes that start with P, H or F are good. All codes that start with L or K are bad. Example:
Email | Code 01 | Code 02 | Code 03 | Code 04 | RESULT
user01#gmail.com | PJR-VRF | | | | GOOD
user01#gmail.com | | LNR-JNT | | LNR-JNT | BAD
user01#gmail.com | | HVB-YWQ | HVB-YWQ | HVB-YWQ | GOOD
user01#gmail.com | | LNR-JNT | | KVB-MMO | BAD
user02#gmail.com | | | | PHH-KLP | GOOD
user02#gmail.com | | HNR-OPT | | LNR-JNT | GOOD
user02#gmail.com | | FLT-MWQ | | FLT-MWQ | GOOD
user02#gmail.com | | KVB-MMO | KVB-MMO | KVB-MMO | BAD
In other words, if a range contains any cells that begin with P, H, or F then good, otherwise bad. I've tried to use the following formula in the result column:
=IF(COUNTIF(B2:E2,{"H*","P*","F*"}),"good","bad")
It didn't work unfortunately, so I tried this:
=IF(COUNTIF(B2:E2,"H*") + COUNTIF(B2:E2,"P*") + COUNTIF(B2:E2,"F*"),"good","bad")
This seems to work, but is this the best method? Say I have 20 other conditions to check against? And need to add a third result? What is the best approach to sift this data?
You can use an array formula similar to this:
=IF(SUM((--($B2:$D2<>""))*(--ISNUMBER(FIND(LEFT($B2:$D2,1),"HPF"))))>0,"GOOD","BAD")
Please remember to press Ctrl+Shift+Enter to complete the array formula correctly.
If you need to add a third result:
=IF(SUM((--($B2:$D2<>""))*(--ISNUMBER(FIND(LEFT($B2:$D2,1),"HPF"))))>0,"GOOD",IF(SUM((--($B2:$D2<>""))*(--ISNUMBER(FIND(LEFT($B2:$D2,1),"EKD"))))>0,"OTHER","BAD"))
I am trying to create a excel file from Matlab with data for multiple cases. The excel file should look something like this:
Case #|____________________________Line 1_____________________________________________|_______ Line 2 _____________ ...
|______Node 1______|______Node 2______|______Node 3______|...|______OverAll_____|
| Min|Max|Mean|Std | Min|Max|Mean|Std | Min|Max|Mean|Std |...| Min|Max|Mean|Std |
|_______________________________________________________________________________|
1| | | | | | | | | | | | | | | | |
2| | | | | | | | | | | | | | | | |
I have the data for each Line>Node in a structured format which I can read through a for loop for a given case. How can I write the values in an excel file? I don't know how to get the next available cell range where I need to place the value. Also, how can I generate such header text dynamically. The number of Nodes and properties (Min/Max/Mean/Std) might change in future.
Thank you for your help. Any suitable tutorial which teaches little advanced xlswrite commands will also help.
Use Activexserver to import whole Excel Functionality in MATLAB using
hApp = actxserver('Excel.Application')
Rest you can use all methods available to Excel Application in MATLAB