GS-Base Help > COM Programming: Samples (C++)

Creating and saving a new database
Adding and removing records, updating calculated fields
Adding, removing, importing, copying and renaming tables and folders
Formatting record fields
Setting column/field widths and row heights
Browsing the folders/tables tree
Searching and sorting
Predefined searching
File password protection
Opening and saving text files
Error handling

The following examples were created in MS Visual Studio C++. (The "community" version can be downloaded from the MS 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. These function wrappers use exceptions as a method of handling errors. If you don't want to use exceptions, please see those headers files for how to use the generic COM system function calls instead.

In higher level languages supporting COM Automation including scripting languages like JScript, VBScript the rules for creating the "GS-Base.Application" object and the other available objects and their interfaces remain in general the same except that you can access object "properties" (see the GS-Base COM interfaces help topic) directly, without the "get_..." and "put_..." functions.

Before the interfaces will be accessible to other programs in the Windows system, they must be registered by GS-Base with the "Register GS-Base COM Interfaces" command (on the GS-Base "Settings" menu).


Creating and saving a new database


#include <stdio.h>
#include <stdio.h>
#include <comdef.h>

#import "E:\gsbase\gsbase.exe"

using namespace GSBASELib;

struct StartOle
{
	StartOle() { ::CoInitialize(NULL); }
	~StartOle() { ::CoUninitialize(); }
} _startOle;

try
{
	IApplicationPtr app;
	app.CreateInstance(L"GSBase.Application");

	IDatabasePtr dbase = app->NewDatabase();

	// insert a new table "table1" in the root ("") folder at the bottom;
	// if "table1" already exists, the uniqueName will contain a unique
	// name table1(1)...table1(n) that GS-Base will create and use instead;
	_bstr_t uniqueName = dbase->InsertDatabaseItem(_bstr_t(""), 1, _bstr_t("table1"));

	IFieldParamsPtr field = dbase->CreateFieldParams();

	// add one Text field to the currently selected table;
	//
	// adding and importing a table make it 'selected' automatically;
	// deleting tables may result in a new selection;
	// SetActiveTable() and GetActiveTable() set and retrieve the selection
	//
	field->put_name(_bstr_t("field1"));
	// T - text field
	// N - numeric field
	// M - long text / Memo
	// O - objects (images, files etc.)
	// C - code field (long text with specific syntax highlighting)
	field->put_type('T');
	dbase->AppendField(field);

	//add one Number field with range validation
	//
	field->Reset();
	field->put_name(_bstr_t("field2"));
	field->put_type('N');
	field->put_formula(_bstr_t("=(field2 > 1) * (field2 < 10)"));
	// 1 - calculation formula/calculated field
	// 2 - validation formula
	// 3 - conversion formula
	// 4 - default value
	// 5 - incremented maximum
	field->put_formulaType(2);
	dbase->AppendField(field);

	//add one calculated Number field
	//
	field->Reset();
	field->put_name(_bstr_t("field3"));
	field->put_type('N');
	field->put_formula(_bstr_t("=field2 * 10"));
	field->put_formulaType(1);
	dbase->AppendField(field);

	//insert one more Text field at the beginning of the record
	field->Reset();
	field->put_name(_bstr_t("field4"));
	field->put_type('T');
	dbase->InsertField(1, field);

	//add one Code field that uses the "cpp" syntax highlighting
	field->Reset();
	field->put_name(_bstr_t("field5"));
	field->put_type('C');
	//subtypes same as in the "Field Setup": "cpp", "assembler", "php"...
	field->put_subtype(_bstr_t("cpp"));
	dbase->AppendField(field);

	//choose to use the standard zip (zip32) file format for the new database;
	the default value for new files is "true" ("use zip64");
	for existing database files their the default value is the one that was used previously;

	//dbase->put_zip64(true);
	dbase->put_zip64(false);

	//save a new database (with one table and no records so far);
	//in c++ the special '\' character in a string must be doubled
	dbase->SaveDatabaseAs(_bstr_t("e:\\test_dbase.gsb"));
	dbase->Close();
}
catch(_com_error error)
{
	// ...
}


Editing an existing database


#include <stdio.h>
#include <stdio.h>
#include <comdef.h>

#import "E:\gsbase\gsbase.exe"

using namespace GSBASELib;

struct StartOle
{
	StartOle() { ::CoInitialize(NULL); }
	~StartOle() { ::CoUninitialize(); }
} _startOle;

try
{
	IApplicationPtr app;
	app.CreateInstance(L"GSBase.Application");

	BSTR password = NULL;
	IDatabasePtr dbase = app->OpenDatabase(_bstr_t("e:\\test_dbase.gsb"), password);

	//all editing actions always refer to the currently selected table;
	//once a table is selected (and the database is saved), it remains selected till you change this;
	//
	if (dbase->GetActiveTable() != _bstr_t("table1"))
		dbase->SetActiveTable("table1");

	//as the table contains the calculated "field3", for performance reasons turn off
	//recalculation of each row which would otherwise occur after each of the 10,000 modifications below;
	//to restore the default automatic updating use "automatic" or re-open the database;
	dbase->put_updateMode(_bstr_t("manual"));

	//Note: for best performance, when inserting a large series of data, always fill the table fields
	//in the "top to bottom" (and "left to right") order. The "bottom to top" order may
	//be considerably slower.

	//insert the following date string in the 1st record field in 10,000 records;
	_bstr_t today = "2021-01-15";
	for (__int64 i = 1; i <= 100000; ++i)
		dbase->InsertText(i, 1, today);

	//insert some numbers in the 3rd record field in the first 10,000 records
	for (__int64 i = 1; i <= 100000; ++i)
		dbase->InsertNumber(i, 3, 2.0 + i%8);

	//update all calculated fields in this table using 4 processor cores
	dbase->UpdateTable(4);

	//get the sum of the 4th field for the entire current record set
	__int64 counter = dbase->GetRecordSetCount();
	double sum = 0;
	for (__int64 i = 1; i <= counter; ++i)
		sum += dbase->GetNumber(i, 4);

	//clear the 3rd field in records 11 to 21
	dbase->ClearRange(11, 3, 21, 3);

	//update all "field3" calculated fields as the "manual" update mode was set earlier
	dbase->UpdateTable(4);

	//remove record 1
	dbase->RemoveRecords(1, 1);
	//remove records 2 to 3
	dbase->RemoveRecords(2, 3);
	//remove record 11
	dbase->RemoveRecords(11, 11);

	dbase->SaveDatabase();
	dbase->Close();
}
catch(_com_error error)
{
	// ...
}


Copying tables and folders


#include <stdio.h>
#include <stdio.h>
#include <comdef.h>

#import "E:\gsbase\gsbase.exe"

using namespace GSBASELib;

struct StartOle
{
	StartOle() { ::CoInitialize(NULL); }
	~StartOle() { ::CoUninitialize(); }
} _startOle;


try
{
	IApplicationPtr app;
	app.CreateInstance(L"GSBase.Application");

	BSTR password = NULL;
	IDatabasePtr dbase = app->OpenDatabase(_bstr_t("e:\\test_dbase.gsb"), password);

	//notes:
	//the special "\" characters in string must be doubled in this c++ code;
	//the trailing "\" determines whether the InsertDatabaseItem method is to create a table or a folder;
	//
	//insert a new folder "folder1\" in the root folder at the bottom;
	//if "folder1" already exists at that level, the uniqueName will contain a unique
	//name folder1(1)...folder1(n) that GS-Base will create and use instead;
	_bstr_t uniqueName = dbase->InsertDatabaseItem(_bstr_t(""), 1, _bstr_t("folder1\\"));

	//insert folder2 at the top
	uniqueName = dbase->InsertDatabaseItem(_bstr_t(""), 0, _bstr_t("folder2\\"));

	uniqueName = dbase->InsertDatabaseItem(_bstr_t("\\folder1\\"), 1, _bstr_t("folder1\\"));
	uniqueName = dbase->InsertDatabaseItem(_bstr_t("folder1"), 1, _bstr_t("folder1\\"));

	//import the "product" table form the sample.zip database and insert it in the root folder
	uniqueName = dbase->ImportTable(_bstr_t("e:\\sample.zip"), _bstr_t("products"), password, _bstr_t("\\"));

	//import it again and insert it in the "folder1" folder
	uniqueName = dbase->ImportTable(_bstr_t("c:\\sample.zip"), _bstr_t("products"), password, _bstr_t("folder1"));

	//create text file parameters
	ITextParamsPtr txt = app->CreateTextParams();
	//use "," as the field separator
	txt->put_separator(_bstr_t("*"));

	//import a new table from the "text_abc.txt" text file and place it in the "folder2" folder
	uniqueName = dbase->ImportTextTable(_bstr_t("c:\\test_abc.txt"), txt, _bstr_t("\\folder2\\"));
	//import it again (the name of the imported table will be modified to "text_abc(1)")
	uniqueName = dbase->ImportTextTable(_bstr_t("c:\\test_abc.txt"), txt, _bstr_t("\\folder2\\"));
	//import it again (the name of the imported table will be modified to "text_abc(2)")
	uniqueName = dbase->ImportTextTable(_bstr_t("c:\\test_abc.txt"), txt, _bstr_t("\\folder2"));

	//rename the "text_abc(2)" table in the "\folder2" folder to "test_abc_b";
	uniqueName = dbase->RenameDatabaseItem(_bstr_t("\\folder2\\test_abc(2)"), _bstr_t("test_abc_b"));

	//copy the "\folder2\test_abc_b" table to "\folder1" and place it at the top, before "products" table
	uniqueName = dbase->CopyDatabaseItem(_bstr_t("\\folder2\\test_abc_b"), _bstr_t("\\folder1\\products"));

	//copy the entire "\\folder2" - it'll be duplicated as "folder2(1)"
	uniqueName = dbase->CopyDatabaseItem(_bstr_t("\\folder2\\"), _bstr_t("\\"));

	//delete the entire "folder2" folder
	dbase->DeleteDatabaseItem(_bstr_t("\\folder2\\"));
		
	//delete the "\folder1\test_abc_b" table
	dbase->DeleteDatabaseItem(_bstr_t("\\folder1\\test_abc_b"));

	dbase->SaveDatabase();
	dbase->Close();
}
catch(_com_error error)
{
	// ...
}


Formatting fields


#include <stdio.h>
#include <stdio.h>
#include <comdef.h>

#import "E:\gsbase\gsbase.exe"

using namespace GSBASELib;

struct StartOle
{
	StartOle() { ::CoInitialize(NULL); }
	~StartOle() { ::CoUninitialize(); }
} _startOle;


try
{
	IApplicationPtr app;
	app.CreateInstance(L"GSBase.Application");

	BSTR password = NULL;
	IDatabasePtr dbase = app->OpenDatabase(_bstr_t("e:\\test_dbase.gsb"), password);

	//select the "table1" table in the root folder
	dbase->SetActiveTable(_bstr_t("\\table1"));

	//create formatting settings
	IFormatParamsPtr format = dbase->CreateFormatParams();

	//set the currency format: variable/automatic number of decimals and the exponent value
	//parameters:
	//1. decimals: 0 - 14 | "auto"
	//2. currency position: "$1.1" | "$ 1.1" | "1.1$" | "1.1 $"
	//3. currency symbol: "$", "GBP" etc.
	//4. true - use curly braces for negative values
	//5. true - use red color for negative values
	//
	format->SetCurrencyFormat(_bstr_t("2"), _bstr_t("$1.1"), _bstr_t("gbp"), true, true);

	// other style examples:
	//
	//set the scientific style: 5 decimal digits and the fixed "07" exponent
	//
	//----- format->SetScientificFormat(_bstr_t("5"), _bstr_t("07"));
	//
	//set the scientific style: variable/automatic number of decimals and the exponent value
	//
	//----- format->SetScientificFormat(_bstr_t("auto"), _bstr_t("auto"));
	//
	//
	//set the accounting style
	//parameters:
	//1. decimals: 0 - 14 | "auto"
	//2. currency symbol: "$", "GBP" etc.
	//
	//----- format->SetAccountingFormat(_bstr_t("2"), _bstr_t("gbp"));
	//
	//
	//set the fractional format
	//parameters:
	//1. if the 2nd parameter is "false", (1) is a denominator value 2, 3, ..., n;
	//   if the 2nd parameter is "true", (1) is a fixed number of denominator digits 1...14
	//2. ...
	//
	//----- format->SetFractionFormat(2, true);
	//
	//
	//set the general number format
	//parameters:
	//1. decimals: 0 - 14 | "auto"
	//2. leading zeroes: 0 - 14
	//3. true - use curly braces for negative values
	//4. true - use red color for negative values
	//5. true - use the thousand separator
	//
	//----- format->SetGeneralNumberFormat(_bstr_t("auto"), 5, false, false, true);
	//

	dbase->SetFieldFormat(3, format);

	//set the date format
	//parameters:
	//1. a date pattern: same as in the "Format > Style" window
	//2. 1 - always switch to the current Windows system day/month order ("m/d..." | "d/m...")
	format->SetDateFormat(_bstr_t("m/d/yyyy"), 1);
	dbase->SetFieldFormat(1, format);

	//clear the previously set information
	format->Reset();

	format->put_fontSize(14);
	format->put_boldFont(true);
	dbase->SetFieldFormat(3, format);

	dbase->SaveDatabase();
	dbase->Close();
}
catch(_com_error error)
{
	// ...
}


Setting column/field widths and row heights


#include <stdio.h>
#include <stdio.h>
#include <comdef.h>

#import "E:\gsbase\gsbase.exe"

using namespace GSBASELib;

struct StartOle
{
	StartOle() { ::CoInitialize(NULL); }
	~StartOle() { ::CoUninitialize(); }
} _startOle;


try
{
	IApplicationPtr app;
	app.CreateInstance(L"GSBase.Application");

	BSTR password = NULL;
	IDatabasePtr dbase = app->OpenDatabase(_bstr_t("e:\\test_dbase.gsb"), password);

	if (dbase->GetActiveTable() != _bstr_t("table1"))
		dbase->SetActiveTable("table1");

	//get the 1st column/field width in screen pixels
	unsigned short width = dbase->GetColumnWidth(1);

	//set a new width
	width += 50;
	dbase->SetColumnWidth(1, width);

	//fit the 3rd column/field width to the data in that column/field
	dbase->FitColumnWidth(3, 3);

	//get the 9th row/record height in screen pixels: typically it should be 25px
	unsigned short height = dbase->GetRowHeight(9);

	//set a new height
	height += 20;
	dbase->SetRowHeight(9, height);

	//check the "auto-height" state of the 9th row
	BOOL autoHeight = dbase->GetAutoRowHeight(9);

	//after the previous SetRowHeight() it should be FALSE
	assert(!autoHeight);

	//restore on the "auto-height" state for the 9th row
	dbase->SetAutoRowHeight(9, 9, TRUE);

	//should be TRUE now
	autoHeight = dbase->GetAutoRowHeight(9);
	assert(autoHeight);

	//it should be 25px again
	height = dbase->GetRowHeight(9);

	dbase->SaveDatabase();
	dbase->Close();
}
catch(_com_error error)
{
	// ...
}


Browsing the folders/tables tree


#include <stdio.h>
#include <stdio.h>
#include <comdef.h>

#import "E:\gsbase\gsbase.exe"

using namespace GSBASELib;

struct StartOle
{
	StartOle() { ::CoInitialize(NULL); }
	~StartOle() { ::CoUninitialize(); }
} _startOle;


try
{
	IApplicationPtr app;
	app.CreateInstance(L"GSBase.Application");

	BSTR password = NULL;
	IDatabasePtr dbase = app->OpenDatabase(_bstr_t("e:\\test_dbase.gsb"), password);

	//1st method

	//get the total number of tables and folders in the main/root folder (including nested folders)
	__int64 counter = dbase->GetDatabaseItemCount();

	//iterate through all table/folders
	for (int i = 1; i <= counter; ++i)
	{
		char path[MAX_PATH] = { 0 };
		::strcpy(path, dbase->GetDatabaseItem(i));
		size_t length = ::strlen(path);
		if (length && path[length - 1] == '\\')
		{
			//folder
		}
		else
		{
			//table
		}
	}

	//2nd method

	//get the first "child" element in the specified folder
	_bstr_t bpath = dbase->GetFirstDatabaseItem(_bstr_t("\\folder2(1)\\"));

	//iterate through direct "child" elements of the specified folder (not expanding nested folders)
	while (bpath.length())
	{
		char path[MAX_PATH] = { 0 };
		::strcpy(path, bpath);
		size_t length = ::strlen(path);
		if (length && path[length - 1] == '\\')
		{
			//folder
		}
		else
		{
			//table
		}
		bpath = dbase->GetNextDatabaseItem(bpath);
	}

	dbase->Close();
}
catch(_com_error error)
{
	// ...
}


Searching and sorting


#include <stdio.h>
#include <stdio.h>
#include <comdef.h>

#import "E:\gsbase\gsbase.exe"

using namespace GSBASELib;

struct StartOle
{
	StartOle() { ::CoInitialize(NULL); }
	~StartOle() { ::CoUninitialize(); }
} _startOle;


try
{
	IApplicationPtr app;
	app.CreateInstance(L"GSBase.Application");

	BSTR password = NULL;
	IDatabasePtr dbase = app->OpenDatabase(_bstr_t("e:\\test_dbase.gsb"), password);

	//select the "table1" table in the root folder
	dbase->SetActiveTable(_bstr_t("\\products"));
		
	IFieldParamsPtr fparams = dbase->CreateFieldParams();

	//find the "ProductName" and "UnitPrice" fields;
	//filter "ProductName" and sort "UnitPrice"

	//reset the previous sorting indices - resetting should be used before calling "put_sortIndex()"
	dbase->ResetSorting();

	unsigned short int iname = 0, iprice = 0;

	for (unsigned short int i = 1; i <= dbase->GetFieldCount() && (!iname || !iprice); ++i)
	{
		dbase->GetField(i, fparams);
		BSTR fname = NULL;
		fparams->get_name(&fname);
		if (!iname && _bstr_t(fname) == _bstr_t(L"ProductName"))
		{
			//set the "\Ai" RegEx filter for "ProductName" (=search for names starting with "I");
			//searching is performed automatically if a call to the "SetField" changes the "filter" value;
			//note: in this version the filter type is always "RegEx"
			fparams->put_filter(_bstr_t(L"\\Ai"));

			dbase->SetField(iname = i, fparams);
		}
		if (!iprice && _bstr_t(fname) == _bstr_t(L"UnitPrice"))
		{
			//set the 1 as the sorting index for "UnitPrice";
			//sorting is performed automatically after a call to "SetField" if the "sorting" index is modified;
			//to create a compound sorting index, use subsequent numbers (2, 3...) for further fields;
			//note: using an index not in that strictly incremented manner causes an error;
				
			fparams->put_sortIndex(1);

			// 'A' - ascending order, 'D' - descending order
			fparams->put_sortOrder('A');

			dbase->SetField(iprice = i, fparams);
		}
		if (fname)
			::SysFreeString(fname);
	}

	dbase->SaveDatabase();
	dbase->Close();
}
catch(_com_error error)
{
	// ...
}



Predefined searching


#include <stdio.h>
#include <stdio.h>
#include <comdef.h>

#import "E:\gsbase\gsbase.exe"

using namespace GSBASELib;

struct StartOle
{
	StartOle() { ::CoInitialize(NULL); }
	~StartOle() { ::CoUninitialize(); }
} _startOle;


try
{
	IApplicationPtr app;
	app.CreateInstance(L"GSBase.Application");

	BSTR password = NULL;
	IDatabasePtr dbase = app->OpenDatabase(_bstr_t("e:\\test_dbase.gsb"), password);

	//select the "table1" table in the root folder
	dbase->SetActiveTable(_bstr_t("\\products"));

	//find duplicates in the 5th field
	dbase->FindDuplicates(5, 5);

	//check the results
	__int64 counter1 = dbase->GetRecordTotalCount();
	__int64 counter2 = dbase->GetRecordSetCount();

	//find filtered duplicates in the 5th field (the 2nd and subsequent occurrences of a given duplicated value)
	dbase->FindFilteredDuplicates(5, 5);

	//check the results
	counter1 = dbase->GetRecordTotalCount();
	counter2 = dbase->GetRecordSetCount();

	//find records with the flag "1"
	dbase->FindFlagged(1);

	// ...

	//find the records not included in the current record set
	dbase->FindCompliment();

	// ...

	//clear all filters and display all records
	dbase->FindAll();

	// ...

	dbase->Close();
}
catch(_com_error error)
{
	// ...
}



File password protection


#include <stdio.h>
#include <stdio.h>
#include <comdef.h>

#import "E:\gsbase\gsbase.exe"

using namespace GSBASELib;

struct StartOle
{
	StartOle() { ::CoInitialize(NULL); }
	~StartOle() { ::CoUninitialize(); }
} _startOle;


try
{
	IApplicationPtr app;
	app.CreateInstance(L"GSBase.Application");


	//set a password
	BSTR password = NULL;
	IDatabasePtr dbase = app->OpenDatabase(_bstr_t("e:\\test_dbase.gsb"), password);

	dbase->SetFilePassword(true, _bstr_t("Twofish"), _bstr_t(""), _bstr_t("rocc4545"));

	dbase->SaveDatabase();
	dbase->Close();

	//open a password-protected database
	dbase = app->OpenDatabase(_bstr_t("e:\\test_dbase.gsb"), _bstr_t("rocc4545"));
	//...
	//dbase->SaveDatabase();
	dbase->Close();


	//remove password protection
	dbase = app->OpenDatabase(_bstr_t("e:\\test_dbase.gsb"), _bstr_t("rocc4545"));

	dbase->SetFilePassword(false, _bstr_t("blowfish"), _bstr_t("rocc4545"), _bstr_t((char*)NULL));

	dbase->SaveDatabase();
	dbase->Close();
}
catch(_com_error error)
{
	// ...
}


Opening and saving text files


#include <stdio.h>
#include <stdio.h>
#include <comdef.h>

#import "E:\gsbase\gsbase.exe"

using namespace GSBASELib;

struct StartOle
{
	StartOle() { ::CoInitialize(NULL); }
	~StartOle() { ::CoUninitialize(); }
} _startOle;


try
{
	IApplicationPtr app;
	app.CreateInstance(L"GSBase.Application");

	// 1. Exporting the current record set to a text file
	// -----------------------------------------------

	BSTR password = NULL;
	IDatabasePtr dbase = app->OpenDatabase(_bstr_t("e:\\test_dbase.gsb"), password);

	//select the "table1" table in the root folder
	dbase->SetActiveTable(_bstr_t("\\products"));

	//create text file parameters
	ITextParamsPtr txt = app->CreateTextParams();

	//use ";" as the field separator; the default value is ","
	txt->put_separator(_bstr_t(";"));

	//use of separators can be turned off; the default value is true
	//txt->put_useSeparator(false);

	//use "'" as the quoting symbol; the default value is """
	txt->put_quotingSymbol(_bstr_t("'"));

	//use of quoting symbols can be turned off; the default value is true
	//txt->put_useQuoting(false);

	//save field names in the first row; the default value is true
	txt->put_fieldNames(true);

	//change the text encoding: "utf8" | "windows" | "dos"; the default value is "utf8"
	txt->put_encoding(_bstr_t("utf8"));

	//export the current table to a text file;
	//"dbase" remains the originally opened database and can edited further as usual
	dbase->SaveTextFileAs("e:\\test_b.txt", txt);

	
	// 2. Opening and saving a text file
	// ---------------------------------

	//re-use the above "txt" settings and add new ones

	//if a column contains textual representations of numbers, try converting them to a number field
	txt->put_loadNumbers(true);

	//if a column contains textual representations of dates in various formats, convert these strings
	//to the generic "DT" W3 text representation of dates in GS-Base (please see the "data types" help topic for details).
	txt->put_loadDates(true);

	IDatabasePtr textFile = app->OpenTextFile("e:\\test_b.txt", txt);

	unsigned short int fcounter = textFile->GetFieldCount();

	IFieldParamsPtr fparams = textFile->CreateFieldParams();

	textFile->GetField(1, fparams);
	//
	// ...perform any editing, field changes etc.
	//

	//save the edited text file
	textFile->SaveTextFile(txt);

	textFile->Close();

	dbase->Close();


	// 3. Opening a text file and saving it as a database
	// --------------------------------------------------

	//re-use the above "txt"
	txt->put_loadNumbers(false);

	textFile = app->OpenTextFile("e:\\test_b.txt", txt);

	//SaveDatabaseAs changes "textFile" to a database with the path given below; the text file is closed
	textFile->SaveDatabaseAs(_bstr_t("e:\\sample_b.gsb"));

	//
	// ...perform any editing, field actions etc. with "e:\\sample_b.gsb"
	//

	textFile->Close();

	dbase->Close();
}
catch(_com_error error)
{
	// ...
}


Error handling


#include <stdio.h>
#include <stdio.h>
#include <comdef.h>

#import "E:\gsbase\gsbase.exe"

using namespace GSBASELib;

struct StartOle
{
	StartOle() { ::CoInitialize(NULL); }
	~StartOle() { ::CoUninitialize(); }
} _startOle;


try
{
	IApplicationPtr app;
	app.CreateInstance(L"GSBase.Application");

	BSTR password = NULL;
	IDatabasePtr dbase = app->OpenDatabase(_bstr_t("e:\\test_dbase.gsb"), password);

	//
	// ...
	//

	// if a COM function returns an error other than E_OUTOFMEMORY,
	// additional error information can obtained via the "lastError" property;
	BYTE code = 0;
	dbase->get_lastError(&code);

	// 21	// Out of memory while creating/editing worksheet data
	// 22	// A database must contain at least one table
	// 37	// Invalid password.
	// 53	// Not allowed field type change - e.g. conversion from "Files/Images" to "Number"
	// 61	// Can't open the specified file
	// 62	// Can't open or create the specified file
	// 63	// Error while closing the specified file
	// 64	// Error while repositioning a file pointer
	// 65	// Error while reading from a file
	// 66	// Error while writing to a file
	// 67	// Error while deleting a file
	// 68	// Error while checking the file size/info
	// 69	// Error while allocating a file read/write buffer
	// 70	// Can't open the specified file. File in use.
	// 71	// Error while decrypting a file.
	// 72	// Error while encrypting a file.
	// 73	// Error while reading binary fields.
	// 79	// Can't find the manifest file or its content is incorrect
	// 80	// The file format requires a newer GS-Base version.
	// 119	// Too many zip streams in a standard zip (zip32) file
	// 120	// Inconsistent zip stream state
	// 121	// Corrupted zip stream data
	// 122	// Out of memory while processing a zip stream
	// 123	// Unexpected end of zip stream
	// 125	// Unknown zlib error
	// 131	// Some data in the file can't be converted to numeric field values.

	dbase->Close();
}
catch(_com_error error)
{
	// ...
}


Related Topics

Interfaces