Excel open xml sdk - Get an empty cell - excel

I have excel file that I need to locate a cell at.
This cell might have attributes like formatting, data validations rules etc. but no value.
I need to retrieve it even if the cell has (currently) no value since I want to maintain all the cell attributes and only set it a value.
Is it possible?
The code:
public static Cell GetSpreadsheetCell(WorksheetPart worksheetPart, string addressName)
{
return worksheetPart.Worksheet.Descendants<Cell>().
Where(c => c.CellReference == addressName).FirstOrDefault();
}

It seems this is not a real a problem.
Data validation is a side object that store references to cells it applies to. When a formula is inserted the cell always contain some value...

Related

gspread clear specific cell value

I want to clear the value of a specific cell. Currently my script runs roughly as follows:
cell_list = worksheet.range(1, 1, len(rows), column_length)
for cell in cell_list:
cell.value = rows[cell.row - 1][cell.col - 1]
worksheet.update_cells(cell_list)
I want just overwrite my old Data to save some API calls, therefore I don't use a worksheet.clear() before. Some of the new values could be None, these cells should be cleared then.
My Problem is:
If I have e.g in cell B2 the value "a" and I set now to B2 to the value "None" (cell.value = None) and I update the Worksheet "a" will stay in B2. So it didn't update the cell, the old value stay.
I could set B2 to an empty string, but the problem with that is, that that is not an empty cell, therefore If I want to sort after it (in the Browser) it will list it at the top because it is an empty string and not empty. If I then clear the cell manually in the browser and sort it again, it sorts it how I want to.
Updated description:
I have a cell list that I want to update with new values in my table. It can happen that a cell contains a value before, but the updated cell should not contain a value anymore.
So the old value of A1 is e.g. "5" and the new value for A1 should be nothing.
The problem is, if I assign the value None to the cell in the cell list, the cell will keep the old value after the update. So the value is still "5".
If I pass an empty string into the cell for updating, the new cell is empty, as desired. But now there is the problem that sorting doesn't work properly for me, so this is not an option for me. I could also clear the whole table before, but I try to avoid this to save API calls.
So I'm looking for a way to tell a cell that it does not contain a value
I think that the reason of your issue is worksheet.update_cells(cell_list). In gspread, it seems that the default value of ValueInputOption is RAW. I think that by this, such error occurs. So in order to avoid this, please modify as follows.
From:
worksheet.update_cells(cell_list)
To:
worksheet.update_cells(cell_list, value_input_option='USER_ENTERED')
By this modification, I think that "" which is the empty string can be used for clearing the cells.
References:
update_cells(cell_list, value_input_option='RAW')
ValueInputOption

Disable warning about Excel text cell containing numeric value in OfficeOpenXml

I'm using OfficeOpenXml to create an MS/Excel spreadsheet file. Some of the columns contain arbitrary text values. However, when cells in those columns are filled with numeric values (i.e., text values containing only digits), Excel displays those cells with a small green triangle in the corner, along with the warning that "The number in this cell is formatted as text or preceded by an apostrophe".
Which is technically correct, but I do not want Excel to display the warning.
So how do I format those columns, or the cells in those columns, to be strictly text values, so that they will not be flagged as numeric text values? How do I disable the warning, and force Excel to accept those cell values as text (only)?
Note: I've seen solutions for other OpenXML packages, but none specifically for OfficeOpenXml. I've also seen solutions for interpreting text cell values as numbers, but this is the exact opposite of what I want to do.
Using DocumentFormat.OpenXml code in C# will look like this.
// Append sheetData to worksheet
worksheet.Append(sheetData);
// Ignoring errors for parsing
IgnoredErrors errors = new IgnoredErrors();
errors.AddChild(new IgnoredError() { NumberStoredAsText = true, SequenceOfReferences = new ListValue<StringValue>() { InnerText = "A:Z" } });
// of type Worksheet
worksheet.Append(errors);
I was looking for the same answer and I think this will get you close.
After the SheetData section, you need to create an IgnoredErrors section with IgnoredError elements. You can do a range such as:
<ignoredErrors>
<ignoredError numberStoredAsText="1" sqref="G2:G10"/>
</ignoredErrors>
You can create more than one element and you can span other types of fields.
In my case, I used the range "A1:{LastCell}" and it worked.
I figured it out by creating my "bad" xlsx document, going into excel and marking the range to ignore and saving as a copy. Then I used the Open XML 2.5 productivity tool compare files to see the difference. It didn't take long to find ignorederrors section and go from there.
Another solution is to us LoadFromText, which fills the cell text and seems to suppress the 'numeric text' warnings for the cell. So I use code like this for filling the cells that have this problem:
DataRow dr = ...; // Query result row
...
cell[r, c].LoadFromText(Convert.ToString(dr["item"]));

Programaticallt Setting an Excel Cell Value that has Validation on it

I have an application that populates an Excel file with data. One of the cells being populated has Cell Validation on it based on a list. When the populated form is opened, I am seeing that my application populates the cell, the value is being seen as invalid, despite the value being in the list.
I am populating the cell value in this manner:
mainSheet.Cells[rowNum, colNum] = cellValue;
Does anyone know what information I am missing to set a cell value to a valid value?
I solved the problem myself. The code was populating the cell with a STRING value. The linked list to the drop down consisted only of INTEGER values. STRING <> INTEGER so the DV routines were reporting a failure. Populating the cell with an INT value resulted in success.

Using the OpenXmlSDK, how can I select/update the value in a cell that is a range-control?

I'm not even sure if I'm using the correct terminology; I will update the question and title as required.
I'm using the OpenXmlSDK to populate a pre-existing Excel 2010 .xlsm file - a macro-enabled worksheet.
I can access worksheets and cells fairly well.
However, I can't figure out how to either access or update the data in a cell that is a dropdown-control that takes its values from a range on another worksheet.
It's labelled as "H13" on the worksheet, and right-click >> format control shows
Input range: 'anotherWorksheet'!$N$3:$N$54
Cell link: 'anotherWorksheet'!$M$3
Whenever I try to get a reference to this cell, I can't find it -- I get a null value
I've tried two access methods:
I'm not even sure if I'm using the correct terminology; I will update the question and title as required.
I'm using the OpenXmlSDK to populate a pre-existing Excel 2010 .xlsm file - a macro-enabled worksheet.
I can access worksheets and cells fairly well.
However, I can't figure out how to either access or update the data in a cell that is a dropdown-control that takes its values from a range on another worksheet.
It's labelled as "H13" on the worksheet, and right-click >> format control shows
Input range: 'anotherWorksheet'!$N$3:$N$54
Cell link: 'anotherWorksheet'!$M$3
Whenever I try to get a reference to this cell, I can't find it -- I get a null value
I've tried two access methods:
// http://msdn.microsoft.com/en-us/library/ff921204.aspx
private static Cell GetCell(Worksheet worksheet, string addressName)
{
return worksheet.Descendants<Cell>().Where(
c => c.CellReference == addressName).FirstOrDefault();
}
and:
// Given a worksheet, a column name, and a row index,
// gets the cell at the specified column and
// http://stackoverflow.com/questions/527028/open-xml-sdk-2-0-how-to-update-a-cell-in-a-spreadsheet
private static Cell GetCell(Worksheet worksheet, string columnName, uint rowIndex)
{
Row row = GetRow(worksheet, rowIndex);
if (row == null)
return null;
return row.Elements<Cell>().Where(c => string.Compare
(c.CellReference.Value, columnName +
rowIndex, true) == 0).FirstOrDefault();
}
// Given a worksheet and a row index, return the row.
private static Row GetRow(Worksheet worksheet, uint rowIndex)
{
return worksheet.GetFirstChild<SheetData>().
Elements<Row>().Where(r => r.RowIndex == rowIndex).First();
}
Both yield null for the target cell H13, but provide references to surrounding cells (ie, `H12, H14, G13'
Actually, I13 also yields null, but that cell is not populated with anything. However, if I can't get a reference, how could I populate it with the SDK? Not my main point, here.
I will be receiving data that will match one of the entries in the dropdown; I just need to actually populate/select that particular entry in the target spreadsheet.
How can I do this with the OpenXmlSDK? I've tried using various open-source libraries, but none seem to support .xslm files (file provided by the client, and cannot be used in another format; macros must execute on launch, etc.).
Although I'm using C#, since my question is about the OpenXmlSDK, I would accept answers in other languages using that framework.
Short Answer: The cell does not exist, thus the null reference.
I created a small worksheet with a list (dropdown) DataValidation pointing to a range of cells in another worksheet.
Reflecting the file using the Open XML SDK 2.0 Productivity Tool I saw that instead of a cell being created and appended to the worksheet, a DataValidation (with a CellReference equating to the target) was created, instead.
using X14 = DocumentFormat.OpenXml.Office2010.Excel;
[....]
X14.DataValidations dataValidations1 = new X14.DataValidations() { Count = (UInt32Value)1U };
dataValidations1.AddNamespaceDeclaration("xm", "http://schemas.microsoft.com/office/excel/2006/main");
X14.DataValidation dataValidation1 = new X14.DataValidation() { Type = DataValidationValues.List, AllowBlank = true, ShowInputMessage = true, ShowErrorMessage = true };
X14.DataValidationForumla1 dataValidationForumla11 = new X14.DataValidationForumla1();
Excel.Formula formula1 = new Excel.Formula();
formula1.Text = "Lists!$A$1:$A$51";
dataValidationForumla11.Append(formula1);
Excel.ReferenceSequence referenceSequence1 = new Excel.ReferenceSequence();
referenceSequence1.Text = "A1";
dataValidation1.Append(dataValidationForumla11);
dataValidation1.Append(referenceSequence1);
dataValidations1.Append(dataValidation1);
Unless the worksheet location has a preset value, it will not actually "be" a "cell" when accessed at run-time.
In retrospect, it makes sense. But visually, it looks like a cell, so it's not obvious....
NOT A CELL:
NOTE: if a selection is made from the DataValidation, and saved, the cell now has a value, and so it exists:
IS A CELL:
This can be worked-around by creating and appending a new cell to the target row when a null reference is returned.
The difficulty now lies in the validation requiring a reference to the shared strings table, and will not accept raw-text as the cell value....
UPDATE: I was able to find the DataValidation associated with the cell, find the target worksheet and range, find the target value within that range, and get the SharedStringsTable reference associated with that value. But no matter value I plugged into the target cell, it was all considered bad data by Excel upon opening.
In the end, I gave up, went slinking back to Excel Interop, and was find a method to select a dropdown field from within (ugh) Interop.

Apache POI - XSSF: Row.getCell()

I am using XSSF to access the .xlsx format. Extracting row data and cell data is being done by
Row.getCell(1) // to get the first cell data.
Is there a way to access cells like
Row.getCell(A) or Row.getCell(AC).
This will be very helpfull for me to access columns.
Can any one tell me the way to do this?
I think the main class you're looking for is CellReference - it handles converting between user facing references such as "B2" into file format references like row=1,col=1 . There's a static method on there that handles your exact use case, convertColStringToIndex
For your use case, you'd want code something like
Cell c = row.getCell( CellReference.convertColStringToIndex("G") );
The question is regarding reaching out a cell using its references, if I am not wrong.
Sheet referenceSheet = workbook.getsheet("Sheet name your intrested in");
CellReference ref = new CellReference("C24");
Row row = referenceSheet.getRow(ref.getRow());
// null check for the row
if(row != null)
{
Cell cell = row.getCell(ref.getCol());
}
In this way we can refer a cell using its reference.

Resources