ClosedXML read from excel file - closedxml

I have an excel file. I simply need a cell value. I am having a hard time finding documentation on this. I have done ClosedXML before where I write date to an excel file but not where I read from it.
const string fileName =
#"C:\Folder1\Form.xlsx";
// Retrieve the value in cell A1.
var workbook1 = new XLWorkbook(fileName);
var ws1 = workbook1.Worksheet(1);
Any help would be appreciated.

There are multiple possibilities to get a cell and its value depending on the data type:
var cell = ws.Cell("A1");
var cell = ws.Cell(1, 2); // row 1, column 2
object result = cell.Value;
string result = cell.Value.ToString(); // if you want to get text
string result = cell.GetValue<string>(); // also for text
int result = cell.GetValue<int>(); // for integer numbers
And more for other datatypes.

Related

I can't get text from RichTextValue

I can't get a text value from RichTextValue which is from a date cell.
The target sheet looks like this:
| date | string | string |
I want to get a text value from first cell.
So I write this code:
const dataRange = sheet.getDataRange().getRichTextValues();
dataRange.forEach((row) => {
const text = row[0].getText();
Logger.log(text);
});
But the log was empty. I can't get a text value from only date cell.(I can get texts from other cells like row[1] or row[2])
How can I get a text value from a date cell?
Issue and workaround:
In the current stage, it seems that with getRichTextValues, the date object and the numbers cannot be retrieved. When those values are retrieved, no values are returned. About "getRichTextValues doesn't retrieve number values", this has already been reported to Google issue tracker. Ref I thought that this issue tracker might be the same with your situation.
I thought that this might be related to that the text format of the part of characters of the date object and number cannot be changed as "RichText".
So, in the current stage, when you want to retrieve the date object as the string value, how about using getDisplayValues instead of getRichTextValues? When your script is modified, it becomes as follows.
Modified script:
const dataRange = sheet.getDataRange().getDisplayValues();
dataRange.forEach((row) => {
const text = row[0];
Logger.log(text);
});
References:
Google issue tracker: getRichTextValues doesn't retrieve number values
getDisplayValues()
You can set formats all cells to String, get their rich values, and restore formats back. Here is the code:
function myFunction() {
const sheet = SpreadsheetApp.getActiveSheet();
const range = sheet.getDataRange();
// store orig formats of cells
const formats_orig = range.getNumberFormats();
// set all cells to String
const formats_string = formats_orig.map(row => row.map(cell => '#'));
range.setNumberFormats(formats_string);
// or you can do it this way:
// range.setNumberFormat('#');
// grab rich values
const dataRange = range.getRichTextValues();
dataRange.forEach((row) => {
const text = row[0].getText();
Logger.log(text);
});
// restore formats
range.setNumberFormats(formats_orig);
}
Perhaps it makes sense to apply String format to the first column only. I suppose you know how it can be done. Just in case:
const formats_string = formats_orig.map(x => ['#'].concat(x.slice(1)));
// or
sheet.getRange('A:A').setNumberFormat('#');

I am trying to create a function within google app scripts that parses a specific value from and places that value within my google spreadsheet

function getEarnings() {
var url = 'http://finviz.com/quote.ashx?t=ntct';
var text = UrlFetchApp.fetch(url)
var pageHtml = text.getContentText();
var doc = XmlService.parse(pageHtml);
var 1yrReturns = getElementsByClassName();
var sheet = SpreadsheetApp.getActive(EQUITY DB);
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
return (doc);
}
This is what I have thus far but I got stuck on XmlService portion of the code, this is for a very important class so PLEASE HELP!
It is easier to use importhtml. Enter this in the cell of your spreadsheet that you want 25.6% returned to:
=ArrayFormula( SUBSTITUTE( index(importhtml("http://finviz.com/quote.ashx? t=ntct","table",11),4,6) , "*" , "" ) )
To explain, if you enter the following, it will return the entire table:
=importhtml("http://finviz.com/quote.ashx?t=ntct","table",11)
index lets you pick the value you want from the table. In this case row 4, column 6 (the ,4,6). You can get any value from the table by its row and column.
The data is returned with asterisks before and after. The substitute replaces "*" with "".
I hope this helps.

Converting Sheet data to a new Sheet

I'm trying to use Google Apps Script to communicate with Google Sheets to do the following:
We're trying to convert data from one Point of Sale system to a new one. In order to do this, I need to take certain columns of a sheet, manipulate them in various ways, and repopulate another sheet with the resulting data. I need to find products without a SKU number, and assign them a new one, starting at 10110 and incrementing from there.
function sku() {
// "From" Spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("New POS Data");
// "To" Spreadsheet
// Spreadsheet key: the string at the end of the URL
var ssraw = SpreadsheetApp.openById("1BH-j4cOW9Ntg6FlPNXmNCUId_pm9BgyAh0cwrwB4z_A");
var sheetraw = ssraw.getSheetByName("Old POS Data");
var max = sheet.getLastRow();
// SKU / UPC
var range = sheetraw.getRange(2,18,max);
var data = range.getValues();
// Assign new sku if no old one
var skunum=[10110];
var newData = new Array();
for (var y = 0; y <= max; y++) {
if (data[y]==""){
newData.push(skunum);
skunum++;
var skunum=[skunum];
}
else {newData.push(data[y]);}
}
sheet.getRange(2,3,max).setValues(newData);
}
This gives me the error "Incorrect range height, was 1 but should be 30 (line 26, file "SKU")"
If I remove the brackets around newData in the last line, I get "Cannot convert Array to Object[][]. (line 27, file "")"
This has been driving me mental, if anyone can offer help, I would be very grateful.
Even if you get a one row or one column vector with getData() you will get an Object[][].
when you do:
if (data[y]==""){
newData.push(skunum);
skunum++;
var skunum=[skunum];
}
You check if [cellFromColumn] == "" which will evaluate to false as it's an array.
You then push the new/old sku number to a simple array which, for spreadsheets, is one row of columns.
Instead you want to push into the array a one element array containin the sku number like this:
newData.push(skunum);
...
newData.push([data[y]]);
This will create an array of rows, each row is an array with one element (one column)

insertRowsBefore() Method causing error: cannot convert (range) to class

I was trying to write a script in google spreadsheets that, will read a range from a defined cell, take its value and Insert as many rows as the range would indicate, and then copy and paste an specific range also given by a range value in a cell.
Apparently the copy and paste range value works, but the range value for the insertRowsBefore is unable to convert the range value, any idea why this happens? I get this error
cannot convert (range) to class
here is how the scripts looks like:
function CopyActualvsWMS() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("ActualVsSystem");
var value0 = sheet.getRange('T4');
var r1 = value0.getValue();
var insert =ss.getSheetByName("DataBase").insertRowBefore(r1);
var value1 = sheet.getRange('T3');
var cr1 = value1.getValue();
var source = ss.getRange(cr1);
source.copyTo(ss.getRange("DataBase!a2"), {contentsOnly: true});
}
The problem is coming from this line:
var insert =ss.getSheetByName("DataBase").insertRowBefore(r1);
You are putting a variable name r1 into the parameter, but the parameter must be a number (integer), not a string or a range reference. The variable r1 doesn't evaluate to an integer. It's probably a string.
Google Documentation - insertRowBefore()

writing delimited text as a string to a spreadsheet

i have a short script where i'm trying to grab data from a URL and write it to a sheet of an existing spreadsheet. the script is as follows:
function urlDataImport() {
var input = "https://reports.acc-q-data.com/clientreports/ecaldwell_201206192722/ecaldwell_20122722.txt";
// The code below gets the HTML code.
var response = UrlFetchApp.fetch(input);
var data = response.getContentText();
Logger.log(data);
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ptSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("pt");
ptSheet.getActiveRange().setValues(data);
}
the information in data is tab delimited and shows up properly in the log but because it's a string i can't use .setValues to write it to the sheet pt and i'm not sure how to get the information from the URL in any other way.
i'm sorry for the rudimentary nature of this question but i'm very new to scripting so any help would be appreciated.
Updated Code:
function ptDataImport() {
var input = "https://reports.acc-q-data.com/clientreports/ecaldwell_201206192722/ecaldwell_2012062.txt";
var response = UrlFetchApp.fetch(input); // Get the data from the URL as an object.
var data = response.getContentText(); // Convet the object to text
var dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("pt"); // Get the sheet to write the data to
var rows = data.split('\n'); // Splits the text into rows
dataSheet.clear();
var dataSet = new Array();
for ( var i in rows){
dataSet[i] = rows[i].split('\t'); // Split the rows into individual fields and add them to the 2d array
}
dataSet.pop(); // Had a blank row at the bottom that was giving me an error when trying to set the range - need to make this conditional somehow
var numColumns = dataSet[0].length;
var numRows = dataSet.length;
var lastRow = dataSet[(numRows -1)];
dataSheet.getRange(1,1,numRows,numColumns).setValues(dataSet); // Get a range the size of the data and set the values
}
#Serge, I think Evan's question was different. Evan is concerned that the split does not take rows into consideration.
The solution to that is to use two splits. First,
var rows = data.split('\n');
And then
for ( var i in rows){
tmp = rows[i].split('\t'); // Use Serge's method if this doesn't work
/* Get the range here */
range.setValues([tmp]);
}
Range.setValues() takes a 2-D array as input.
I'm not sure what you want to do. If all you want to do is write data into a cell, then use this piece of code
ptSheet.getActiveRange().setValues([[data]]);
If you want to write each of the elements in data to a row in a spreadsheet, then you can use
var tmp = data.split(DELIMITER);
/* Get the correct range here */
range.setValues([tmp]);
Notice how you are creating a 2-D array in the first case and in the second case.
I guess the easiest thing to do is to convert those tabs in something else, commas for example, that's after all where the 'c' of csv comes from... you can then write it wherever you want.
Exemple :
commaString = tabString.replace(\t/g,',') ; should work but I'm not an expert in regEx... if I'm wrong someone will for sure correct it ;-)