Get Range of Cells Value as Display using Microsoft.Office.Interop.Excel - excel-interop

I am programming with C# to access data from a range of cells in Excel Spreadsheet.
I can use the following code to access and return the values of range of cells into an object array.
(object[,])Mysheet.UsedRange.get_Value(XlRangeValueDataType.xlRangeValueDefault);
However, I like to find a mean to return all data as strings (exactly as shown on the spreadsheet) into a string array or putting the values as text into the object array. Are there any mechanism to do that>

Did you try using .Text in the Range object? As far as I know, you will have to iterate over each cell and do it for each of them.
Note that .Text is considerably heavy in terms of performance compared to Value or Value2.
And also note that it is also tricky, .Text returns the text as you would see it if you had Excel visible, so if you have a huge number in a column with a short width what .Text will give you is a lot of ####
Sadly I can't think of another way to get it. Usually I get the raw values and format them properly once a get them all, but that assumes that I know which format is used in which cells.

Related

Does anyone know how to use the Options Clause in Google Sheets Query Function?

I've been studying the Query Function for quite some time now, but I still don't know how to use the Options Clause. Can someone explain how to use it? Thank you very much.
From the documentation on:
Data Table Class
Each cell in the table holds a value. Cells can have a null value, or a value of the type specified by its column. Cells optionally can take a "formatted" version of the data; this is a string version of the data, formatted for display by a visualization. A visualization can (but is not required to) use the formatted version for display, but will always use the data itself for any sorting or calculations that it makes (such as determining where on a graph to place a point). An example might be assigning the values "low" "medium", and "high" as formatted values to numeric cell values of 1, 2, and 3.
Within Google Sheets, however, it seems not to have any effect.
It is intended for the JavaScript Visualization API, and the sheets implementation of QUERY is similar but will not behave in exactly the same way. There is a corresponding method setFormattedValue(rowIndex, columnIndex, formattedValue) which allows you to set formatted values, if you want them. The example given in the docs says that instead of showing numbers, for the sake of a certain visualization you may want to display "high", "medium" or "low" instead.
In Sheets:
Using the JOIN function to get the raw values:
=JOIN(" ", QUERY(A:A,"Select A options no_values"))
and
=JOIN(" ", QUERY(A:A,"Select A options no_format"))
It will take the format of the first value and coerce the subsequent values into that format. Even the number at the end.
If you change the first value format:
You'll now get this:
In both cases you'll see that options has no effect.
I've not used it, but this is the official description:
https://developers.google.com/chart/interactive/docs/querylanguage#options

Is there a way to specify an input is a single cell in Google Sheets?

I want to iterate over an array of cells, in this case B5:B32, and keep the values that are equal to some reference text in a new array.
However, SPLIT nowadays accepts arrays as inputs. That means that if I use the array notation of "B5:B32" within ARRAYFORMULA or FILTER, it treats it as a range, rather than the array over which we iterate one cell at a time.
Is there a way to ensure that a particular range is the range over which we iterate, rather than the range given at once as an input?
What I considered was using alternative formulations of a cell, using INDEX(ROW(B5), COLUMN(B5)) but ROW and COLUMN also accept array values, so I'm out of ideas on how to proceed.
Example code:
ARRAYFORMULA(
INDEX(
SPLIT(B5:B32, " ", 1), 1
) = "Some text here"
)
Example sheet:
https://docs.google.com/spreadsheets/d/1H8vQqD5DFxIS-d_nBxpuwoRH34WfKIYGP9xKKLvCFkA/edit?usp=sharing
Note: In the example sheet, I can get to my desired answer if I create separate columns containing the results of the SPLIT formula. This way, I first do the desired SPLITS, and then take the values I need from that output by specifying the correct range.
Is there a way to do this without first creating an output and then taking a cell range as an input to FILTER or other similar functions?
For example in cell C35 I've already gotten the desired SPLIT and FILTER done in one go, but I'd still need to find a way to sum up the values of the first character of the second column. Doing this requires that I take the LEFT value of the second column, but for that I need to output the results and continue in a new cell. Is there a way to avoid this?
Ralph, I'm not sure if your sample sheet really reflects what you are trying to end up with, since, for example, I assume you are likely to want the total of the hours per area.
In any case, this formula extracts all of the areas, and the hours worked, and is then easy to do further calculations with.
=ArrayFormula({REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9},"(.*) \d"),
VALUE(REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9}," (\d+)hrs"))})
Try that in cell E13, to see the output.
The first REGEXEXTRACT pulls out all the text in front of the first space and number, and the second pulls out all the digits in a string of " #hr" in each cell. These criteria could be modified, if necessary, depending on your actual requirements. Note that it requires the use of VALUE, to convert the hours from text to numeric values, since REGEXEXTRACT produces text (string) results.
It involved concatenating your multiple data columns into one long column of data, to make it simpler to process all the cells in the same way.
This next formula will give you a sum, for whatever matching room/task you type into B6, as an example.
=ArrayFormula(QUERY({REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9},"(.*) \d"),
VALUE(REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9}," (\d+)hrs"))},
"select Col1, sum(Col2) where Col1='"&B6&"' group by Col1 label sum(Col2) '' ",0))
I will also answer my own question given what I know from kirkg13's answer and other sources.
Short answer: no, there isn't. If you want to do really convoluted computations with particular cell values, there are a few options and tips:
Script your own functions. You can expand INDEX to accept array inputs and thereby you can select any set of values from an array without outputting it first. Example that doesn't use REGEXMATCH and QUERY to get the SUM of hours in the question's example data set: https://docs.google.com/spreadsheets/d/1NljC-pK_Y4iYwNCWgum8B4NJioyNJKYZ86BsUX6R27Y/edit?usp=sharing.
Use QUERY. This makes your formula more convoluted quite quickly, but is still a readable and universally applicable method of selecting data, for example particular columns. In the question's initial example, QUERY can retrieve only the second column just like an adapted INDEX function would.
Format your input data more effectively. The more easily you can get numbers from your input, the less you have to obfuscate your code with REGEXMATCHES and QUERY's to do computations. Doing a SUM over a RANGE is a lot more compact of a formula than doing a VALUE of a LEFT of a QUERY of an ARRAYFORMULA of a SPLIT of a FILTER. Of course, this will depend on where you get your inputs from and if you have any say in this.
Also, depending on how many queries you will run on a given data set, it may actually be desirable to split up the formula into separate parts and output partial results to keep the code from becoming an amalgamation of 12 different queries and formulas. If the results don't need to be viewed by people, you can always choose to hide specific columns and rows.

QUERY function not including text cells along with number cells in result

I'm currently trying to copy a list using the QUERY function in google-sheets.
The problem im now facing is that words / letters are not included in the search.
Example picture
Im using the function: "=QUERY(E2:F5;)" but don't get the words included.
Is there any way to include these words by using the formula above as guide?
In google-sheets, use Format, Number, Plain Text on your source range of E2:F5 and your original formula will work.
=QUERY(E2:F5)
From Docs Editor Help - QUERY function
In case of mixed data types in a single column, the majority data type determines the data type of the column for query purposes. Minority data types are considered null values.

Google spreadsheets query() is replacing text with null for mostly numeric columns [duplicate]

This question already has answers here:
Query is ignoring string (non numeric) value
(2 answers)
Closed 5 months ago.
I have =query(importrange(...);"select * where Col1>' '") formula in my spreadsheet.
Importrange() by itself works ok, loading all the cells from source spreadhseet exactly as they are.
But Col7 contains few text cells, but mostly numbers, and when query() is applied -- numbers are kept as they are, but text is replaced with blank.
I've tried adding options no_format at the end of the query, with no difference.
Here's the contents of Col7, first line gets replaced with blank:
free
41,25
34,25
34,25
48,25
41,25
QUERY won't return columns with mixed data types by design:
In case of mixed data types in a single column, the majority data type
determines the data type of the column for query purposes. Minority
data types are considered null values.
The workaround will depend on how you want to use your data afterwards, and what compromises you would be willing to make. For example you could fairly easily convert the entire dataset into text strings, so that everything will be retained, but then all your numbers will be text strings as well.
If you needed to retain numbers as numbers, often the best bet will be to ImportRange the entire dataset somewhere in your spreadsheet (could be on a hidden sheet), and then use an alternative to QUERY on that (namely FILTER).
You can use vlookup for the columns that need to be a mixed data type. Query the unique row identifier and then vlookup the rest. I often use the following formula:
=arrayformula(if(isblank(A:A), "", vlookup(A:A, search_range, col_index, FALSE)))
Change the format of the whole column to plain text.
The numbers will still read as numbers, and the minority text values will retain their text values. Nothing will be counted as null.

Google Sheets - get the right-most value of a row

I have a sheet where the columns are months in a year and the rows are various metrics. Every month, we add another column on the right.
I need something that I can give a ROW and it will always return the right most value. That is, it automatically updates whenever we add a column for a new month.
There's a few ways of doing it, but one way (considering row 2 in this example):
=FILTER(2:2,COLUMN(2:2)=MAX(FILTER(COLUMN(2:2),LEN(2:2))))
I was very happy to have found #AdamL's answer and it did make my day, but I have since found a simpler way that works fine for my data sample, and that is using the LOOKUP function.
The LOOKUP function will look for a certain value in a given range, but if you pass it a humongous value, a value that is over your data range, it returns the last, rightmost value by default.
The answer is then very simple, just pass it the range - or row if that's what you need - and a huge value (many people do this using the biggest number that Excel can handle, but Google sheets is not Excel, and since I don't know what is the biggest number Google sheets can handle, I'll just give it a value well outside of my data set). Assuming you need to lookup into the entire row number 2:
=LOOKUP(999999999,2:2)
And that's it.
This function will throw an error if there isn't any data, so if you (like me) need to get that particular value only if it exists, you can combine this with a simple IF function:
=IF(ISERROR(LOOKUP(999999999,2:2)),"EMPTY",LOOKUP(999999999,2:2))
You can replace the string "EMPTY" with any value or function you want in there if the LOOKUP function returns an error.
I hope this simpler method is of any help, and thanks again to #AdamL for his original answer.
Adding this one for future readers. The formula I found years ago for obtaining the rightmost value was:
=index(2:2,1,COUNT(2:2))
However for each blank cells in amongst the cells with data, the returned value is the Nth last value (2 blank cells in row 2 and the formula will return the 3rd last value from the right, not the rightmost value). It appears to work, but won't be accurate in all cases.
As such, I do not recommend this formula as you can not depend on it if ever there will be an empty cell before the right-most within your data.

Resources