Sample Index
The following examples were created in MS Visual Studio C++. (The "Community" version can be downloaded from the Microsoft website at no cost.)
The examples use "smart pointers" and function wrappers with declarations and definitions automatically generated as header and source files
by MS VS C++ when you use the #import directive.
The main() definitions are skipped for brevity. These function wrappers use exceptions as a method of handling errors.
If you do not want to use exceptions, please refer to those header files for instructions on using generic COM system function calls instead.
For the complete list of interface definitions, please see Interfaces, methods and properties.
These interfaces are also used in GS-Calc to support scripting. In scripting languages like JScript and VBScript, the rules for creating
and using the "GS-Calc.Application" object and other available objects/interfaces remain generally the same, except that you can access
object properties directly without the get_... and put_... functions. In both cases, the methods and functions
are identical and use the same parameters described in the Methods, properties and sample usage
scripting help topic.
Before these interfaces are accessible to other programs in the Windows system, they must be registered by GS-Calc using the Register GS-Calc COM Interfaces command (found in the GS-Calc "Settings" menu).
Creating and saving a new workbook
#include <stdio.h>
#include <comdef.h>
#import "E:\gscalc\gscalc.exe"
using namespace GSCALCLib;
struct StartOle
{
StartOle() { ::CoInitialize(NULL); }
~StartOle() { ::CoUninitialize(); }
} _startOle;
try
{
IApplicationPtr app;
app.CreateInstance(L"GSCalc.Application");
//create a new workbook with the default "sheet1" worksheet
IWorkbookPtr wbook = app->NewWorkbook();
//alternatively, add another worksheet
//wbook->InsertWorksheet(_bstr_t("sheet2"));
IWorksheetPtr wsheet = wbook->GetActiveWorksheet();
//turn off automatic updating of formulas for best performance
//
//"default" - as defined in the global application settings
//"automatic" - updating after each cell data change
//"manual" - updating only with the "Update All/Worksheet" commands
wbook->put_updateMode(_bstr_t("manual"));
//insert a series of numbers 1 to 10000 in c1:c10000
for (int i = 1; i <= 10000; ++i)
{
wchar_t buffer[20] = { 0 };
wsheet->InsertNumberRC(i, 3, (double)i);
}
//alternatively, the InsertData() function can be used, however
//it performs additional checks, conversions, autoformatting and activating "undo"
//which results in a much slower (up to several hundreds of times) execution (see the corresponding help topic for details)
/*
for (int i = 1; i <= 10000; ++i)
{
char buffer[20] = { 0 };
::_itoa(i, buffer, 10);
wsheet->InsertData(wsheet->Address(3, i), _bstr_t(buffer), true);
}
*/
//insert a label and a formula to sum the above numbers
wsheet->InsertTextRC(10001, 1, _bstr_t("sample sum"));
wsheet->InsertFormulaRC(10001, 3, _bstr_t("=sum(c1:c10000)"));
//add a comment
wsheet->InsertCommentsRC(10001, 3, _bstr_t("sum of numbers from c1 to c10000"));
//if it's necessary recalculate all worksheets and update the views;
wbook->UpdateAllWorksheets();
//if updating is performed in the background, wait until it's complete
wbook->WaitForUpdate();
//or simply update the screen (as the "Insert[...]RC" functions don't refresh the screen)
//wsheet->UpdateWindow();
//save a workbook using the native *.gsc format;
//specifying the *.ods extension causes saving it in the ODF format
wbook->SaveAs(_bstr_t("e:\\sample111.gsc"));
wbook->Close();
}
catch(_com_error error)
{
// ...
}
Editing an existing workbook
#include <stdio.h>
#include <comdef.h>
#import "E:\gscalc\gscalc.exe"
using namespace GSCALCLib;
struct StartOle
{
StartOle() { ::CoInitialize(NULL); }
~StartOle() { ::CoUninitialize(); }
} _startOle;
try
{
IApplicationPtr app;
app.CreateInstance(L"GSCalc.Application");
//open the sample.gsc workbook
IWorkbookPtr wbook = app->OpenWorkbook(_bstr_t(L"e:\\sample.gsc"), (BSTR)NULL);
//set the default active worksheet;
//once it's set and the file is saved it'll remain the active one after re-opening;
if (::_wcsicmp(wbook->GetActiveWorksheetPath(), _bstr_t(L"data types")))
wbook->SetActiveWorksheet(_bstr_t(L"data types"));
IWorksheetPtr wsheet = wbook->GetActiveWorksheet();
//add 1.0 to the cell C1
double v1 = wsheet->GetNumberRC(1, 3);
v1 += 1.0;
wsheet->InsertNumberRC(1, 3, v1);
//not using the WaitForUpdate() function will cause terminating the current updating process
//and restarting it after another cell change below
//wbook->WaitForUpdate();
//insert formula in C5 (Row 5, Col 3)
wsheet->InsertFormulaRC(5, 3, _bstr_t("=sum(c1:c4)"));
//if the update mode it set to "manual", update formulas explicitly;
//wbook->UpdateActiveWorksheet();
//if updating is performed in the background, wait until it's complete
wbook->WaitForUpdate();
//from the C5 cell get the formula, its value and optionally an error code;
//note: if a formula returns a text string, the IsFormulaTextualRC() functions returns TRUE
//and the GetTextRC() function must be used to obtain its current value
_bstr_t formula = wsheet->GetFormulaRC(5, 3);
double v2 = wsheet->GetNumberRC(5, 3);
BYTE errorCode = wsheet->IsErrorRC(5, 3);
//assuming it's a console app, print the data
if (!errorCode)
::wprintf(L"%s %s -> %g", static_cast<wchar_t*>(wsheet->AddressRC(5, 3)), static_cast<wchar_t*>(formula), v2);
else
::wprintf(L"%s %s -> error (%u)", static_cast<wchar_t*>(wsheet->AddressRC(5, 3)), static_cast<wchar_t*>(formula), errorCode);
//clear the C1 cell;
//deleting and formatting cells/ranges requires selecting the respective range;
//the 2nd parameter in DeleteCells can be a string with the following substrings:
//data numbers labels formulas formatting lists comments;
//data = numbers labels formulas
wsheet->put_selectedRange(wsheet->AddressRC(1, 3));
wsheet->DeleteCells(false, _bstr_t("data"));
//if the update mode it set to "manual", update formulas explicitly;
//wbook->UpdateActiveWorksheet();
//if updating is performed in the background, wait until it's complete
wbook->WaitForUpdate();
errorCode = wsheet->IsErrorRC(5, 3);
//print the data again
if (!errorCode)
::wprintf(L"\n%s %s -> %g", static_cast<wchar_t*>(wsheet->AddressRC(5, 3)), static_cast<wchar_t*>(formula), wsheet->GetNumberRC(5, 3));
else
::wprintf(L"\n%s %s -> error (%u)", static_cast<wchar_t*>(wsheet->AddressRC(5, 3)), static_cast<wchar_t*>(formula), errorCode);
//insert the n/a! error code in C1
wsheet->InsertData(wsheet->AddressRC(1, 3), _bstr_t("#N/A!"), true);
//if the update mode it set to "manual", update formulas explicitly;
//wbook->UpdateActiveWorksheet();
//if updating is performed in the background, wait until it's complete
wbook->WaitForUpdate();
errorCode = wsheet->IsErrorRC(5, 3);
//print the data again
if (!errorCode)
::wprintf(L"\n%s %s -> %g", static_cast<wchar_t*>(wsheet->AddressRC(5, 3)), static_cast<wchar_t*>(formula), wsheet->GetNumberRC(5, 3));
else
::wprintf(L"\n%s %s -> error (%u)", static_cast<wchar_t*>(wsheet->AddressRC(5, 3)), static_cast<wchar_t*>(formula), errorCode);
//save changes
wbook->Save();
wbook->Close();
}
catch(_com_error error)
{
// ...
}
Copying and pasting cell ranges
#include <stdio.h>
#include <comdef.h>
#import "E:\gscalc\gscalc.exe"
using namespace GSCALCLib;
struct StartOle
{
StartOle() { ::CoInitialize(NULL); }
~StartOle() { ::CoUninitialize(); }
} _startOle;
try
{
IApplicationPtr app;
app.CreateInstance(L"GSCalc.Application");
//open the sample.gsc workbook
IWorkbookPtr wbook = app->OpenWorkbook(_bstr_t(L"e:\\sample.gsc"), (BSTR)NULL);
//set the default active worksheet;
//once it's set and the file is saved it'll remain the active one after re-opening;
if (::_wcsicmp(wbook->GetActiveWorksheetPath(), _bstr_t(L"data types")))
wbook->SetActiveWorksheet(_bstr_t(L"data types"));
IWorksheetPtr wsheet = wbook->GetActiveWorksheet();
//select the range to copy
wsheet->put_selectedRange(wsheet->AddressRC(1, 3) + _bstr_t(L":") + wsheet->AddressRC(5, 3));
//copy
//1 - copy all data including formulas
//5 - copy all data with formula values instead of formulas
wsheet->CopyCells(1);
//select the top-left cell for the inserted data
wsheet->put_selectedRange(wsheet->AddressRC(1, 4));
//paste the copied cells
//true - paste data and formatting
//false - paste only data, preserving the existing formatting
wsheet->PasteCells(true);
//select the range to paste
wsheet->put_selectedRange(wsheet->AddressRC(1, 5) + _bstr_t(L":") + wsheet->AddressRC(15, 6));
//paste the copied cells;
//the data will be duplicated within that range
wsheet->PasteCells(true);
//if updating is performed in the background, wait until it's complete
wbook->WaitForUpdate();
//save changes
wbook->Save();
wbook->Close();
}
catch(_com_error error)
{
// ...
}
Formatting
#include <stdio.h>
#include <comdef.h>
#import "E:\gscalc\gscalc.exe"
using namespace GSCALCLib;
struct StartOle
{
StartOle() { ::CoInitialize(NULL); }
~StartOle() { ::CoUninitialize(); }
} _startOle;
try
{
IApplicationPtr app;
app.CreateInstance(L"GSCalc.Application");
//open the sample.gsc workbook
IWorkbookPtr wbook = app->OpenWorkbook(_bstr_t(L"e:\\sample.gsc"), (BSTR)NULL);
//set the default active worksheet;
//once it's set and the file is saved it'll remain the active one after re-opening;
if (::_wcsicmp(wbook->GetActiveWorksheetPath(), _bstr_t(L"data types")))
wbook->SetActiveWorksheet(_bstr_t(L"data types"));
IWorksheetPtr wsheet = wbook->GetActiveWorksheet();
//select the range C1:C5
wsheet->put_selectedRange(wsheet->AddressRC(1, 3) + _bstr_t(L":") + wsheet->AddressRC(5, 3));
IFormatParamsPtr format = wsheet->CreateFormatParams();
//set the scientific format leaving the default options
//parameters:
//1. a number of decimals: auto|0...14
//2. an exponent: auto|-99...99
format->SetScientificFormat(_bstr_t("auto"), _bstr_t("auto"));
//format C1:C5
wsheet->SetCellFormat(format);
//clear previously used formatting attributes
format->Reset();
// set the italic attribute
format->put_italicFont(true);
wsheet->SetCellFormat(format);
format->Reset();
// set a new font and all its attributes
format->put_italicFont(TRUE);
format->put_underlineFont(TRUE);
format->put_strikeoutFont(TRUE);
format->put_boldFont(TRUE);
format->put_fontColor(_bstr_t("white")); //or format->put_fontColor(_bstr_t("#FFFFFF"));
format->put_fontSize(15);
format->put_fontName(_bstr_t("Courier"));
wsheet->SetCellFormat(format);
format->Reset();
//set new cell filling
format->put_bkgColor(_bstr_t("green")); //or format->put_fontColor(_bstr_t("#00FF00"));
//set new cell border attributes;
//border type parameter:
//0 - remove borders
//1 - top
//2 - bottom
//4 - left
//8 - right
//16 - diagonal left
//32 - diagonal right
//64 - auto
format->put_borderPosition(1 | 2 | 4 | 8);
format->put_borderColor(_bstr_t("blue"));
//border style parameter:
//none | solid | dot | dash | dash-dot | dash-dot-dot
format->put_borderStyle(_bstr_t("solid"));
format->put_borderWidth(2);
wsheet->SetCellFormat(format);
//save changes
wbook->Save();
wbook->Close();
}
catch(_com_error error)
{
// ...
}
Browsing the worksheet tree
#include <stdio.h>
#include <comdef.h>
#include <assert.h>
#import "E:\gscalc\gscalc.exe"
using namespace GSCALCLib;
struct StartOle
{
StartOle() { ::CoInitialize(NULL); }
~StartOle() { ::CoUninitialize(); }
} _startOle;
try
{
IApplicationPtr app;
app.CreateInstance(L"GSCalc.Application");
//open the sample.gsc workbook
IWorkbookPtr wbook = app->OpenWorkbook(_bstr_t(L"e:\\sample.gsc"), (BSTR)NULL);
// 1. browse the folder containing the active worksheet; don't list nested folders
_bstr_t folder = wbook->GetParentFolder(wbook->GetActiveWorksheetPath());
_bstr_t itemPath = wbook->GetFirstTreeItem(folder);
size_t counter = 0;
while (itemPath.length())
{
if (wbook->IsFolder(itemPath))
{
::wprintf(L"\n%zu. Folder: %s", ++counter, static_cast<wchar_t*>(itemPath));
}
else
{
::wprintf(L"\n%zu. Worksheet: %s", ++counter, static_cast<wchar_t*>(itemPath));
//
//... e.g. wbook->SetActiveWorksheet(itemPath)...
//
}
itemPath = wbook->GetNextTreeItem(itemPath);
}
::wprintf(L"\n\n");
// 2. browse the entire worksheet tree; list nested folders
//an arbitrary chosen max. nesting level for the sample.gsc folders
_bstr_t stack[5];
size_t level = 0;
itemPath = wbook->GetFirstTreeItem((BSTR)NULL);
counter = 0;
while (itemPath.length())
{
if (wbook->IsFolder(itemPath))
{
::wprintf(L"\n%zu. Folder: %s", ++counter, static_cast<wchar_t*>(itemPath));
_bstr_t itemPath2 = wbook->GetFirstTreeItem(itemPath);
if (itemPath2.length() && level < 5)
{
stack[level++] = itemPath;
itemPath = itemPath2;
continue;
}
}
else
{
::wprintf(L"\n%zu. Worksheet: %s", ++counter, static_cast<wchar_t*>(itemPath));
//
//... e.g. wbook->SetActiveWorksheet(itemPath)...
//
}
itemPath = wbook->GetNextTreeItem(itemPath);
if (!itemPath.length() && level)
itemPath = wbook->GetNextTreeItem(stack[--level]);
}
assert(counter == static_cast<size_t>(wbook->GetWorksheetCount()) + wbook->GetFolderCount());
wbook->Close();
}
catch(_com_error error)
{
// ...
}
Inserting, copying and removing worksheets and folders
#include <stdio.h>
#include <comdef.h>
#import "E:\gscalc\gscalc.exe"
using namespace GSCALCLib;
struct StartOle
{
StartOle() { ::CoInitialize(NULL); }
~StartOle() { ::CoUninitialize(); }
} _startOle;
try
{
IApplicationPtr app;
app.CreateInstance(L"GSCalc.Application");
//open the sample.gsc workbook
IWorkbookPtr wbook = app->OpenWorkbook(_bstr_t(L"e:\\sample.gsc"), (BSTR)NULL);
//copy/duplicate the "data types" worksheet within the main folder;
//the worksheet will be inserted as "data types(1)"
wbook->CopyTreeItem(_bstr_t(L"data types"), (BSTR)NULL);
//create a new folder in the main/root folder;
//the InsertFolder()/InsertWorksheet() functions require names without paths as parameters
//and folders/sheets are inserted in the active folder
wbook->SetActiveFolder((BSTR)NULL);
wbook->InsertFolder(_bstr_t(L"new-folder"));
//copy the worksheet "data types" from the main folder to the folder "new-folder";
wbook->CopyTreeItem(_bstr_t(L"data types"), _bstr_t(L"new-folder"));
//copy it again - the worksheet name will be "data types(1)"
wbook->CopyTreeItem(_bstr_t(L"data types"), _bstr_t(L"new-folder"));
//create a new nested folder in the folder "new-folder";
//the InsertFolder()/InsertWorksheet() functions require names without paths as parameters
//and folders/sheets are inserted in the active folder
wbook->SetActiveFolder(_bstr_t(L"new-folder"));
wbook->InsertFolder(_bstr_t(L"new-nested-folder"));
//move "data types(1)" to "new-nested-folder"
wbook->MoveTreeItem(_bstr_t(L"new-folder\\data types(1)"), _bstr_t(L"new-folder\\new-nested-folder"));
//create a new folder in the main/root folder
wbook->SetActiveFolder((BSTR)NULL);
wbook->InsertFolder(_bstr_t(L"new-folder2"));
//copy the folder "2d charts" from the main folder to "new-folder2"
wbook->CopyTreeItem(_bstr_t(L"2D charts"), _bstr_t(L"new-folder2"));
//delete the active folder "2d charts" along with its worksheets;
//the DeleteTreeItem() function applies to the currently selected worksheet or folder
wbook->SetActiveFolder(_bstr_t(L"2d charts"));
wbook->DeleteTreeItem();
//move the "3d charts" folder to "new-folder2";
wbook->MoveTreeItem(_bstr_t(L"3d charts"), _bstr_t(L"new-folder2"));
//pause execution to allow for manual result verification
::Sleep(10000);
//close without saving
wbook->Close();
}
catch(_com_error error)
{
// ...
}
Password protection and encryption
#include <stdio.h>
#include <comdef.h>
#import "E:\gscalc\gscalc.exe"
using namespace GSCALCLib;
struct StartOle
{
StartOle() { ::CoInitialize(NULL); }
~StartOle() { ::CoUninitialize(); }
} _startOle;
try
{
IApplicationPtr app;
app.CreateInstance(L"GSCalc.Application");
//open the sample.gsc workbook
IWorkbookPtr wbook = app->OpenWorkbook(_bstr_t(L"e:\\sample.gsc"), (BSTR)NULL);
wbook->SetFilePassword(true, _bstr_t(L"blowfish"), _bstr_t(""), _bstr_t("Rk4@m7"));
wbook->SaveAs(_bstr_t(L"e:\\sample_p.gsc"));
wbook->Close();
//open the protected sample.gsc workbook
wbook = app->OpenWorkbook(_bstr_t(L"e:\\sample_p.gsc"), _bstr_t("Rk4@m7"));
//
//...
//
wbook->Close();
}
catch(_com_error error)
{
// ...
}
Saving and editing text files
#include <stdio.h>
#include <comdef.h>
#import "E:\gscalc\gscalc.exe"
using namespace GSCALCLib;
struct StartOle
{
StartOle() { ::CoInitialize(NULL); }
~StartOle() { ::CoUninitialize(); }
} _startOle;
try
{
IApplicationPtr app;
app.CreateInstance(L"GSCalc.Application");
//open the sample.gsc workbook
IWorkbookPtr wbook = app->OpenWorkbook(_bstr_t(L"e:\\sample.gsc"), (BSTR)NULL);
ITextParamsPtr txt = app->CreateTextParams();
txt->put_separator(_bstr_t("\t"));
wbook->SetActiveWorksheet(_bstr_t(L"Pivot tables\\customers"));
//save the "customers" worksheet as a text file;
//don't display dialog boxes with options
wbook->SaveAsTextFile(_bstr_t("e:\\sample_123.txt"), false, txt);
//close the text file
wbook->Close();
//open the "e:\\sample_123.txt" text file;
//show the dialog box with text options
wbook = app->OpenTextFile(_bstr_t("e:\\sample_123.txt"), true, txt);
//
// ... edit the file
//
//to save the file with modified parameters, the SaveAsTextFile() function must be used
txt->put_separator(_bstr_t(","));
//set the utf16 encoding (the default one was "utf8")
txt->put_encoding(_bstr_t("utf16"));
wbook->SaveAsTextFile(_bstr_t("e:\\sample_123.txt"), false, txt);
//to save it using the originally used "txt" parameters, the Save() function can be used
//wbook->Save();
wbook->Close();
}
catch(_com_error error)
{
// ...
}
Printing
#include <stdio.h>
#include <comdef.h>
#import "E:\gscalc\gscalc.exe"
using namespace GSCALCLib;
struct StartOle
{
StartOle() { ::CoInitialize(NULL); }
~StartOle() { ::CoUninitialize(); }
} _startOle;
try
{
IApplicationPtr app;
app.CreateInstance(L"GSCalc.Application");
//open the sample.gsc workbook
IWorkbookPtr wbook = app->OpenWorkbook(_bstr_t(L"e:\\sample.gsc"), (BSTR)NULL);
//set the default active worksheet;
//once it's set and the file is saved it'll remain the active one after re-opening;
if (::_wcsicmp(wbook->GetActiveWorksheetPath(), _bstr_t(L"data types")))
wbook->SetActiveWorksheet(_bstr_t(L"data types"));
IWorksheetPtr wsheet = wbook->GetActiveWorksheet();
IPrintSettingsPtr prn = wsheet->CreatePrintSettings();
//get the default print settings for this worksheet
wsheet->GetPrintSettings(prn);
//modify some options
prn->put_autoFit(true);
prn->put_marginTop(15 /*mm*/);
//save back the modified settings
wsheet->SetPrintSettings(prn);
//print the worksheet; don't display the "Print" dialog box
wsheet->Print(false);
wbook->Close();
}
catch(_com_error error)
{
// ...
}
Saving ranges as *.png images
#include <stdio.h>
#include <comdef.h>
#import "E:\gscalc\gscalc.exe"
using namespace GSCALCLib;
struct StartOle
{
StartOle() { ::CoInitialize(NULL); }
~StartOle() { ::CoUninitialize(); }
} _startOle;
try
{
IApplicationPtr app;
app.CreateInstance(L"GSCalc.Application");
//open the sample.gsc workbook
IWorkbookPtr wbook = app->OpenWorkbook(_bstr_t(L"e:\\sample.gsc"), (BSTR)NULL);
//set the default active worksheet;
//once it's set and the file is saved it'll remain the active one after re-opening;
if (::_wcsicmp(wbook->GetActiveWorksheetPath(), _bstr_t(L"data types")))
wbook->SetActiveWorksheet(_bstr_t(L"data types"));
IWorksheetPtr wsheet = wbook->GetActiveWorksheet();
wsheet->put_selectedRange(_bstr_t(L"c1:c5"));
wsheet->SaveSelectionAsImage(_bstr_t(L"e:\\image_c1c5.png"));
wbook->Close();
}
catch(_com_error error)
{
// ...
}
Related Topics