Setting Excel Number Format via xlcFormatNumber in an xll - c++

I'm trying to set the number format of a cell but the call to xlcFormatNumber fails leaving the cell number format as "General". I can successfully set the value of the cell using xlSet.
XLOPER xRet;
XLOPER xRef;
//try to set the format of cell A1
xRef.xltype = xltypeSRef;
xRef.val.sref.count = 1;
xRef.val.sref.ref.rwFirst = 0;
xRef.val.sref.ref.rwLast = 0;
xRef.val.sref.ref.colFirst = 0;
xRef.val.sref.ref.colLast = 0;
XLOPER xFormat;
xFormat.xltype = xltypeStr;
xFormat.val.str = "\4#.00"; //I've tried various formats
Excel4( xlcFormatNumber, &xRet, 2, (LPXLOPER)&xRef, (LPXLOPER)&xFormat);
I haven't managed to find any documentation regarding the usage of this command. Any help here would be greatly appreciated.

Thanks to Simon Murphy for the answer:-
Smurf on Spreadsheets
//It is necessary to select the cell to apply the formatting to
Excel4 (xlcSelect, 0, 1, &xRef);
//Then we apply the formatting
Excel4( xlcFormatNumber, 0, 1, &xFormat);

Related

Spreadsheet Script, match with wildcard and different cases

I am having trouble executing the Spreadsheet script below.
I think there are two mistakes but I do not know how to fix.
Could anyone help it to fix it?
1:Wildcard
if(original_date=='....-..-..')
2:if synteax
if(original_date=='....-..-..')
{condition="matched"}
Detail
On the spreadsheet, there are two columns.
The first columns have dates in a format as YYYY-MM-DD such as 2020-04-21.
But sometimes, they have different formats such as 04/21/2020.
The second columns are empty.
Only when the first column cell has the "YYYY-MM-DD" format, I want to copy the cell into the second cell in the second column.
*They have 10 rows.
Here is the script.
var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1')
for(let i=1; i<=10; i++)
{
original_date_range = sheet.getRange(i, 1);
original_date = original_date_range.getValue();
cleaned_date_range = sheet.getRange(i, 2);
var condition = "";
if(original_date=='....-..-..')
{condition="matched"}
switch(condition)
{
case "matched":
cleaned_date_range.setValue(original_date);
case "":
cleaned_date_range.setValue("");
break;
}
}
I found the solution by myself.
1.Wildcard
The date "2020-04-25" can be written as /\d{4}.\d{2}.\d{2}/
2.If syntax
(Wildcard).test(string to check) is going to give you true/false output
In summary,
if you want to execute different tasks through the verification of date format such as 2020-04-25,
var sheet1 = SpreadsheetApp.getActive().getSheetByName('Sheet1')
var limit = sheet1.getLastRow()
for(let i=4; i<=10; i++) //You can add more rows if you have
{
var orignal_date_cell = sheet1.getRange(i, 1);
var orignal_date_cell_value = orignal_date_cell.getValue();
var target_date_cell = sheet1.getRange(i,2);
if ((/\d{4}.\d{2}.\d{2}/).test(orignal_date_cell_value))
{
target_date_cell.setValue(orignal_date_cell_value);
}
}

SpreadsheetFormats not working as expected

I am able to populate data from a query into a spreadsheet. However, I am having problems getting "ranged" formatting to work properly. The formatting for specific column (date) and row (header) work fine. But SpreadsheetFormatColumns, ...Rows, ...CellRange is not. I need to set the font and fontsize to the whole dataset.
Here is what I have tried.
<cfscript>
//Current directory path.
theFile = GetDirectoryFromPath(GetCurrentTemplatePath()) & "GridDump.xls";
//Create a new Excel spreadsheet object and add the query data.
theSheet = SpreadsheetNew("Raw Data");
FormatDate.dataformat = "dd-mmm-yy";
//Get Row Count and Row Range
RC = toString(result.recordcount+1);
RR = "1-" & RC;
//Get Column Count
CC = toString(ListLen(GridFieldNames));
//Get Column Letter
CL = chr(CC + 64);
//Get Column Range (Nummerical)
CRN = "1-" & CC;
//Get Column Range (Alphabetical)
CRA = "A-" & CL;
//Set Sheet Format
WholeSheet = StructNew();
WholeSheet.font="Consolas";
WholeSheet.fontsize=12;
//Set header Row Format
HeadRow = StructNew();
HeadRow.bold="true";
//Insert the Header Row
SpreadsheetAddRow(theSheet,GridFieldNames);
//Insert the Data
SpreadsheetAddRows(theSheet,result);
//Format the Data
SpreadsheetFormatCellRange(theSheet,WholeSheet,1,1,RC,CC);
//SpreadsheetFormatRows(theSheet,WholeSheet,RR);
//SpreadsheetFormatColumns(theSheet,WholeSheet,CRN);
SpreadsheetFormatRow(theSheet,HeadRow,1);
//Header Row
SpreadsheetFormatColumn(theSheet,FormatDate,1);//Date Column
SpreadsheetAddFreezePane(theSheet,0,1);//Top Row Only
//SpreadSheetAddAutofilter(theSheet,"A1:J1");
</cfscript>
Here are the results
I'm getting the same result for all three of the "ranged" formatting functions. The format stops part way through the spreadsheet. I expect the whole dataset to accept any of the ranged function formats.
I got the same result with CF 2018,0,04,314546. Could just be a limitation of XLS format.
Switching to XLSX worked fine for me:
theSheet = SpreadsheetNew("Raw Data", true);
YMMV, but what also worked with CF2018 was using SpreadsheetFormatColumns() instead of SpreadsheetFormatCellRange().

Google Script .getvalue() Not Working With Cells With a Formula In It

I have this google script for google sheets that moves rows of data from "Sheet1" to "Sheet2" when column 15 says "tracking", and it works perfectly fine when I type in "tracking" but I would like that column to be an IF equation something like IF(G:G="tracking not available at this time","","tracking"). But the code does not seem to recognize the formula change from "" to "tracking". Do I need to change the getvalue()? Or is there a different workaround to this issue? I've used =query(importrange) withing the spreadsheet to copy over data with a trigger word, but I really want this to be more of an archive system and add a row to the bottom of "Sheet2" whenever row15 on "sheet1"Thanks! Here is the code:
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Sheet1" && r.getColumn() == 14 && r.getValue() == "tracking") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Sheet2");
if(targetSheet.getLastRow() == targetSheet.getMaxRows()) {
targetSheet.insertRowsAfter(targetSheet.getLastRow(), 20);
}
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
I had an issue with this recently
I spent about 3 hours debugging something yesterday and this was the culprit.
try using r.getDisplayValue() instead of r.getValue
I am still new to this myself, and feel free to correct me if I am wrong, because if there is a different reason I would really love to know!!!
It seems that if a value in a cell is not typed in but placed there through a formula such as =query() or a similar method, I don't think it actually sees that there is a value in the cell. (I got null values or the formula itself)
If you use getDisplayValue, it "should" get the value that you actually see in the cell.
The correct way to get formulas, instead of displayed values, is with getFormulas rather than getValues

How to use excel in MS visual C++

I want to make a windows form app. You can write text in textBox'es and when you press a button, the app would create an excel file and write the text from the boxes. I got only the UI done, I know some basics but I have no idea how to combine MS Visual C++ and Excel.
There's a lot of libraries listed in this answer:
What is a simple and reliable C library for working with Excel files?
In addition "ExcelFormat Library" is basic, but it sounds like it will do everything you need. It's free and easy to use.
And Number Duck is a commercial library that I have created.
This is a C # code taken from https://code.google.com/p/excellibrary/,
Play a bit with this code in VC + + and make it work. :)
Syntax are different but if you think about it you'll see it's all the same. ;)
First you have to download ExcelLibrary.dll file and add it to the Reference Project.
Than add this two lines:
using namespace ExcelLibrary::CompoundDocumentFormat;
using namespace ExcelLibrary::SpreadSheet;
The aim of this project is provide a native .NET solution to create, read and modify
Excel files without using COM interop or OLEDB connection.
Currently .xls (BIFF8) format is implemented. In future .xlsx (Excel 2007) may also be
supported.
Example code:
//create new xls file
string file = "C:\\newdoc.xls";
Workbook workbook = new Workbook();
Worksheet worksheet = new Worksheet("First Sheet");
worksheet.Cells[0, 1] = new Cell((short)1);
worksheet.Cells[2, 0] = new Cell(9999999);
worksheet.Cells[3, 3] = new Cell((decimal)3.45);
worksheet.Cells[2, 2] = new Cell("Text string");
worksheet.Cells[2, 4] = new Cell("Second string");
worksheet.Cells[4, 0] = new Cell(32764.5, "#,##0.00");
worksheet.Cells[5, 1] = new Cell(DateTime.Now, #"YYYY\-MM\-DD");
worksheet.Cells.ColumnWidth[0, 1] = 3000;
workbook.Worksheets.Add(worksheet);
workbook.Save(file);
// open xls file
Workbook book = Workbook.Load(file);
Worksheet sheet = book.Worksheets[0];
// traverse cells
foreach (Pair<Pair<int, int>, Cell> cell in sheet.Cells)
{
dgvCells[cell.Left.Right, cell.Left.Left].Value = cell.Right.Value;
}
// traverse rows by Index
for (int rowIndex = sheet.Cells.FirstRowIndex;
rowIndex <= sheet.Cells.LastRowIndex; rowIndex++)
{
Row row = sheet.Cells.GetRow(rowIndex);
for (int colIndex = row.FirstColIndex;
colIndex <= row.LastColIndex; colIndex++)
{
Cell cell = row.GetCell(colIndex);
}
}

C++ Builder and Excel Automation, where to get started?

I want to dynamically create and populate an excel spreadsheet with C++ builder 2009, but I'm not entirely sure how to go about it. Searching the web, I've narrowed it down to using OLE Automation. Moreover, I'm looking for a document or programming tutorial that can get me started. Is there a simple programming tutorial that also thoroughly explains the concepts of OLE automation?
To open an excel spreadsheet:
Variant excelApp = Unassigned;
//EOleSysError is thrown if GetActiveObject does not succeed. i.e
//if Excel is not currently open.
try
{
excelApp = Variant::GetActiveObject("Excel.Application");
}
catch(EOleSysError& e)
{
excelApp = Variant::CreateObject("Excel.Application"); //open excel
}
excelApp.OlePropertySet("ScreenUpdating", true);
To get the current cell pointer:
Variant excelCell = excelSheet.OlePropertyGet("Cells");
To add values to excel:
// create a vararray of 5 elements starting at 0
int bounds[2] = {0, 4};
Variant variantValues = VarArrayCreate(bounds, 1, varVariant);
variantValues.PutElement(5, 0);
variantValues.PutElement(5, 1);
variantValues.PutElement(5, 2);
variantValues.PutElement(5, 3);
variantValues.PutElement(5, 4);
Variant cellRange = excelCell.OlePropertyGet(
"Range",
excelCell.OlePropertyGet("Item", rowindex, columnindex), // start cell
excelCell.OlePropertyGet("Item", rowindex2, columnindex2) // finishing cell
);
// place array into excel
cellRange.OlePropertySet(
"Value",
excelApp.OleFunction("Transpose", variantValues)
);
I hope this gets you started, you will probably need to include vcl.h and comobj.hpp.