Archive

Archive for February, 2013

SliQ Invoicing Plus Version 4 Released

February 17th, 2013

Version 4 of SliQ Invoicing Plus has now been released, 18 months after the release of version 3. Version 4 includes a range of updates requested by our users as well as a refresh in the look of the package.

In version 4, even more flexibility has been included and now customers can customise the standard reports or even copy the reports to create whole new reports. As with our previous versions, all our reports can be exported to Microsoft Excel. Reports can be customised by adding more columns, filtering and sorting any of the columns as well as adding custom groups.

Going along with the theme of increasing flexibility, all the major lists shown in SliQ can also now be customised, e.g. the Invoices & Payments tab list can be customised by adding the invoice delivery address.

The recurring invoices facility has also been overhauled and in V4 it is now possible to create recurring transactions. The new recurring transactions facility makes it easy to change tax rates in the middle of a recurring billing cycle, e.g. if the VAT rate changes.

Many more new features are included in V4 including sales receipts, a sales margin calculator, support for multiple addresses and delivery addresses per customer or supplier, multiple contacts per customer/ supplier, customer price bands and a wizard to help assign customer payments to multiple invoices.

As with our previous major releases, a program of updates is planned on a regular cycle over the new few months.

Version 4 is available for a one-off price and includes a free 30 day trial. V4 is 100% compatible with all previous versions from V1 to V3 and will automatically import and convert all data and settings from older versions when installed on the same PC as a previous version.

For more information on the new features in version 4, check out our Release History page.

Monotouch Exception: This class is not key value coding-compliant …

February 13th, 2013

While writing an iPad application in Monotouch I started getting the following exception while running the program in the iPad simulator:

Objective-C exception thrown.  Name: NSUnknownKeyException Reason: [<MainView 0x99d1460> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key buttonSetup.

Stunned by how unhelpful the exception message was I tried to track down the cause of the error. The only clue the error message gave me was that buttonSetup was the name of a UIButton I had previously had on my main view in the application. However, I had renamed the button so theoretically there were no references to the button left in the project. After reopening the xib for the view in XCode, I tried to track down any remaining reference to the button with no luck until after a few minutes clicking round, I found the following view in Xcode – the Connections Inspector view – which showed a remaining reference to the old button name in the Referencing Outlets:

monotouch-remove-referencing-outlet

To get to the Referencing Outlets section, I clicked on the renamed button (in the pane shown on the left in the pic. above) then opened the Connections Inspector using the toolbar button shown on the top right in the pic. The red rectangle on the bottom right shows the extra referencing outlet to the old control name that I had to remove to get the project to run without an exception. Removing the buttonSetup referencing outlet was easy – just click the x on the File’s Owner widget.

SQLite: How to get the row ID after inserting a row into a table

February 1st, 2013

When working with SQL databases it can often be useful to keep a record of the ID of the row in a table from which a piece of data was read. For example, if you have a Customers table in a database then if you populate a list of Customer objects in your application from the rows in the table, storing the row ID for each object lets you easily update the correct row if you edit the values in one of the Customer objects.

In SQLite, if you have a field of type INTEGER PRIMARY KEY in a table, the database engine will automatically fill the field with the ID for the row. When you insert a new row in the table, e.g. add a new customer into the Customers table taking the example above, then you will need to find out the ID of the new row so you can write it back into the Customer object you’ve just added.

SQLite has a special SQL function – last_row_id() – that returns the ID of the last row inserted into the database so getting the ID of a new row after performing a SQL insert just involves executing the last_row_id() command.

Here is an example in C# showing how to get the ID of the last row inserted into a table in a database.

Create the SQLite database and open a connection to it:

 String mPathName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "testdba.db3");

 SQLiteConnection.CreateFile(mPathName);

 // Open a connection to the database.
 SQLiteConnection Conn = new SQLiteConnection("Data Source = " + mPathName);

 Conn.Open();

Create a table (Customers) in the SQLite database:

 // Create a table.
 //
 String SQL = "CREATE TABLE Customers (ID INTEGER PRIMARY KEY, UNIQUEID VARCHAR(30), ADDRESS VARCHAR(100))";

 SQLiteCommand Command = new SQLiteCommand(SQL, Conn);

 // Create the table.
 //
 Command.ExecuteNonQuery();

Insert a row of data into the table:

 // Reuse the command object and insert a row into the table.
 //
 Command.CommandText = "INSERT INTO Customers (UNIQUEID, ADDRESS) VALUES (@UNIQUEID, @ADDRESS)";

 Command.CommandType = System.Data.CommandType.Text;

 Command.Parameters.Add(new SQLiteParameter("@UNIQUEID", "Fred Bloggs"));
 Command.Parameters.Add(new SQLiteParameter("@ADDRESS", "Acacia Avenue"));

 int Status = Command.ExecuteNonQuery();

Now get the ID of the last row inserted:

 Command.CommandText = "select last_insert_rowid()";

 // The row ID is a 64-bit value - cast the Command result to an Int64.
 //
 Int64 LastRowID64 = (Int64)Command.ExecuteScalar();

 // Then grab the bottom 32-bits as the unique ID of the row.
 //
 int LastRowID = (int)LastRowID64;

Note that in SQLite the row ID is a 64-bit integer but for all practical database sizes you can cast the 64 bit value to a 32-bit integer.

For more SQLite database tips check out:

http://www.sliqtools.co.uk/blog/net/sqlite-how-to-determine-if-a-columns-exists-in-a-table/