|
|
Subscribe / Log in / New account

Escape from QuickBooks (with data in hand)

By Jonathan Corbet
August 7, 2017

Free accounting systems
When a small business contemplates getting away from a proprietary accounting tool like QuickBooks in favor of free software like GnuCash, the first order of business is usually finding a way to liberate that business's accounting data for input into a new system. Strangely enough, Intuit, the creator of QuickBooks, never quite got around to making that easy to do. But it turns out that, with a bit of effort, this move can be made. Getting there involves wandering through an undocumented wilderness; this article is at attempt to make things easier for the next people to come along.

This article is not a review of GnuCash as a business accounting application — that will come later. But GnuCash seemed like a reasonable place to start. But pity the poor explorer who goes searching for information on how to move from QuickBooks to GnuCash and stumbles into this text in the GnuCash FAQ:

At this time there is no way to import from Quickbooks, and there are no plans to add that functionality. The Quickbooks QBW data format is a proprietary, non-documented file format. So until someone documents the file format or donates a QBW file parser your best bet for importing your QB data into GnuCash would be to output your data in a CSV format and either import the CSV data directly or convert the CSV to QIF and use the QIF importer.

Such discouragement from the authors of the application itself is certainly enough to send the hunt for a new accounting package elsewhere. Interestingly, it seems that most people who have looked at this problem have concluded that the proprietary QuickBooks format makes the whole task impossible. But it is possible to get most of a business's data out of QuickBooks in a relatively useful machine-readable form, especially if your use of QuickBooks is relatively simple. Here is how I did it, starting with QuickBooks Pro 2015.

Liberating the data

It would be nice if one could select an option to extract the entire contents of a QuickBooks company file in some sort of open format. Failing that, one has to do it in two steps, and the result is not quite as complete as one would like.

QuickBooks stores much of its information in "lists", and those can be extracted in the IIF format. IIF is also said to be proprietary, but it's text-based and relatively easy to parse. Even so, some time spent searching for an available Python module for reading IIF was in vain, strangely; there must certainly be many of them out there. Oh well, when in doubt, reinvent a new wheel and go forward.

Anyway, when faced with the QuickBooks main screen, one can follow the menus through FileUtilitiesExportLists to IIF Files and get a dialog with the set of lists that can be written out. The lists of the highest likely interest (and the ones that my importer tool can deal with) are the lists of customers and vendors, and the chart of accounts. There are a number of others available, including the "other names" list, but the purpose of that list seems to have a place to put a name when QuickBooks is absolutely determined to add it to a list, and no other list is applicable. The employee list will be of interest to some, undoubtedly, and perhaps the payment terms list.

The other piece of the puzzle is the set of transactions stored in the general ledger — the data that one uses an accounting system to track. That can be had by pulling up the EditFind dialog, selecting "Advanced", and entering the date range of interest; the result of the search can be exported to a CSV file with the transaction data. Be careful, though: QuickBooks 2015, at least, will silently cap the number of lines written to this file to 32768, so if you have a lot of data to export, it will need to be done in multiple steps.

That gets most of what most people are likely to want, with a couple of exceptions. One is the initial balances for the accounts. The chart of accounts is exported with balance information, but those are the final balances and unlikely to be of any real use. There does not appear to be an easy way to avoid copying down and entering initial balances by hand. The other missing piece is bills and invoices. The relevant entries in accounts payable and accounts receivable will be there, but the surrounding metadata will not. If that data is needed, it will need to be moved by hand — a somewhat painful prospect if one has a lot of outstanding items.

Feeding it to GnuCash

This data, once extracted, can eventually be fed to just about any sort of accounting system, but the job is likely to be different for each. GnuCash, happily, offers a Python-based interface (Python 2 only) that can be used to manipulate its database. Unhappily, one of the most accurate and complete parts of the documentation on the Python bindings can be found on the GnuCash wiki: "Python bindings have been recently added to gnucash. There is still very little documentation and probably few people would know how to use it." Developers wanting to use the Python bindings are left scrounging the web looking for examples to crib from.

It is worth noting that there is another GnuCash interface called piecash. It has the advantages of being better documented and being ported to Python 3. On the other hand, piecash only works with GnuCash files stored in a relational database — a GnuCash mode that appears to be poorly developed and maintained and, as a result, generally not enabled by distributors. The stock GnuCash bindings, instead, will work with both database-backed and native XML files.

What follows is an overview of two programs I wrote using the GnuCash Python bindings. qb_iif_to_gc is a simple importer for the list data extracted above; it needs to be run first to set up a new GnuCash file. Then qb_trans_to_gc can be run to import the transaction data. All of this code can be pulled from the repository listed at the end of this article.

One starts, of course, by installing the Python bindings, which are usually packaged separately from the application. The gnucash module provides access to basic functionality, while gnucash.gnucash_business has some of the more business-oriented features. Beyond that, it's not unusual to need to go beyond what has been provided in those files; in that case, gnucash.gnucash_core_c has a much more extensive — but lower-level — interface generated directly with the SWIG tool.

The first order of business is to open a GnuCash session to work with a file:

    session = gnucash.Session(file, ignore_lock=False, is_new=False,
                              force_new=False)

The file parameter is, of course, the name of the GnuCash file to work with. It uses the URI notation, so the way to specify a local XML file would be with something like xml://path/to/file.gnucash. If the file exists, only the file name needs to be provided and things will work. When creating a new, empty file (by passing is_new=True), though, the full URI must be provided. The ignore_lock parameter can be used to open a file that is locked elsewhere — most helpful when debugging a script that may not have gotten around to properly closing the file the last time it exited.

When the job is done, changes to the session should be written out and the session closed with calls like:

    session.save()
    session.end()

Beyond that, the only real use for the session within a script is to extract session.book, which is the "book" containing the actual accounting data. One other bit of useful data to grab at the outset is the default currency to use with accounts; my scripts do:

    book = session.book
    ctable = book.get_table()
    dollars = ctable.lookup('CURRENCY', 'USD')

LWN is based in the US, so we can happily pretend that everybody just uses dollars and be done with it. If your company manages accounts in more than one currency, a little more attention will need to be paid here.

Accounts

Before much of anything else, it is necessary to set up a chart of accounts. Depending on how one is doing the migration, one might wish to create a new chart by hand or to simply import the chart from QuickBooks. One other small twist is that the GnuCash way of organizing accounts groups them by type in a hierarchy; all expense accounts start with Expenses/, for example. QuickBooks does not do things that way. There appears to be nothing in GnuCash that requires this organization, so following it is a matter of choice. The qb_iff_to_gc tool will, if run with -r, reparent accounts to fit them within the default GnuCash model.

One creates an account in GnuCash by instantiating an Account object, setting its parameters, and slotting it into the hierarchy. The root of the hierarchy can be had by calling the book's get_root_account() method. So a simple example of creating a new income account would look something like this:

    acct = gnucash.Account(book)
    acct.BeginEdit()
    acct.SetName('Advertising Income')
    acct.SetType(gnucash.ACCT_TYPE_INCOME)
    acct.SetCommodity(dollars)
    book.get_root_account().append(acct)
    acct.CommitEdit()

The BeginEdit() and CommitEdit() methods are common to most GnuCash objects and, as one might expect, they are used to bracket a set of changes to that object. There is also a RollbackEdit() method should one change one's mind. One thing that jumps out from the example code found around the net is that almost nobody bothers with these calls except when dealing with Transaction objects. The code works just fine without them, but I feel that they have been provided for a reason and it is probably safer to call them.

The IIF file exported by QuickBooks provides the name and account type, so filling in this information is relatively simple. But the above example creates a top-level account. When creating a hierarchy, there's a bit more to do. LWN's chart of accounts includes one that is exported by QuickBooks as "Professional Fees:Freelance Authors"; in GnuCash that would need to be stored as Professional Fees/Freelance Authors, or even Expenses/Professional Fees/Freelance Authors. Creating that requires walking the hierarchy. The necessary code looks something like this:

    def find_parent(name, root):
        sname = name.split(':')
        parent = root
        for acct in sname[:-1]:
            parent = parent.lookup_by_name(acct)
            if not parent:
                print 'Failed to find container account', acct
                return root, sname[-1]
        return parent, sname[-1]

The parent account returned by this function is the one on which append() should be called to add the new account to the hierarchy. Note that this function assumes that the upper-level accounts already exist. When importing a chart of accounts exported by QuickBooks without changes, that will always be true. If account names are being remapped (a feature built into qb_iff_to_gc), though, that condition may not hold and intermediate accounts may need to be created while walking the tree.

Vendors and customers

An established business is likely to have a long list of vendors and customers; fortunately, those can be imported automatically. Doing the import requires dealing with the GnuCash business interface, which looks a little different from what we have seen so far. A vendor with a given name would be created with a call like:

    vendor = gnucash_business.Vendor(book = book,
                                     id = book.VendorNextID(),
                                     currency = dollars,
                                     name = name)

The explicit call to book.VendorNextID() is needed to get an ID number to associate with the vendor; the rest should be relatively self-explanatory. Setting the vendor's contact information requires a few extra calls, though, to set up an address object:

     addr = vendor.GetAddr()
     addr.BeginEdit()
     addr.SetName(ventry['PRINTAS'] or name)
     addr.SetAddr1(ventry['ADDR1'])
     addr.SetAddr2(ventry['ADDR2'])
     addr.SetAddr3(ventry['ADDR3'])
     addr.SetPhone(ventry['PHONE1'])
     addr.CommitEdit()

Here, ventry is the vendor entry from the QuickBooks IIF file; most of the information copies over in a fairly straightforward way. There is one little glitch, though: sometimes vendors have a tax ID number that must be used for sending (for example) 1099 forms or reports to the government. GnuCash doesn't seem to have a way of storing that number directly, which is a bit of a shortcoming, unfortunately. There is, though, a way of storing notes with a vendor, so I chose to stash the tax ID there. The high-level interface provides no access to the notes, though, so one has to resort to the low-level interface:

    if ventry['TAXID']:
        inst = vendor.get_instance()
        gnucash_core_c.gncVendorSetNotes(inst, ventry['TAXID'])

Let's just say that a certain amount of digging was required to figure that out.

The interface for customer data is almost identical:

    cust = gnucash_business.Customer(book = book,
                                     id = book.CustomerNextID(),
                                     currency = dollars,
                                     name = name)

Once again, a new ID number must be explicitly generated. Contact information for the customer is set by calling its GetAddr() method as is done for vendors above.

And that is the core of the qb_iif_to_gc program; interested readers can read the full script or grab the repository. There is more information that can be exported an imported in this manner; in particular, some will certainly have a need to import employee information. We don't store that information in QuickBooks, though, so I haven't implemented an import function for that data.

Transactions

Once the chart of accounts is in place, it's time to populate the ledger with transaction data; that is the task of the qb_trans_to_gc tool. Importing this data is actually fairly straightforward, but a couple of terms need to be defined first. A "transaction" describes a complete financial operation, such as LWN buying a case of beer using a debit card. A transaction is made up of two or more "splits", each of which describes an entry in a single ledger. In this case, one split is entered into the ledger for the bank account, decreasing its balance by the cost of the beer. The other split increases the balance of the appropriate expense account ("Office Supplies" in this case). The amounts in the splits differ only in sign in this case — the amount paid for the beer equals (the absolute value of) the amount taken from the bank account.

A more complicated transaction can have more splits. Paying an employee may involve a big debit from a bank account, with corresponding splits for the money paid to the employee, taxes paid to the government, withholdings for employee benefits, etc. An LWN subscription purchased with PayPal generate three splits: the funds come in via "Subscription Income", then out to the PayPal "bank" account and the expense account for PayPal fees. Regardless of the number of splits, the amounts involved must add up to zero in the end.

QuickBooks dumps each split into the CSV file as a separate line, with nothing to mark when one transaction stops and the next begins. It does, however, include the in-transaction balance in each line, so a balance of zero is a reasonably good end-of-transaction indicator. It is not foolproof; one could easily construct a transaction with a balance of zero partway through but, in the real world, that tends not to happen. So, by keying on that zero balance, it's possible to assemble a transaction from the splits provided by QuickBooks.

A transaction is, unsurprisingly, represented by a Transaction object, created and initialized with code like the following (where entry) is the first line from the CSV file describing the transaction):

    trans = gnucash.Transaction(book)
    trans.BeginEdit()
    trans.SetCurrency(dollars)
    trans.SetDescription(entry['Name'])
    if entry['Num']:
        trans.SetNum(entry['Num'])
    trans.SetDate(day, month, year)

The description field for a transaction is often the counterparty to the transaction — the beer store, for example. Those of us old enough to remember writing checks will also remember that they have a number associated with them; if a number is present, SetNum() can be used to add it here.

Note that nothing done so far describes any money changing hands; that's all done in the splits. Before getting there, though, we should look at how GnuCash represents numbers like currency amounts. These amounts are often given as decimal values, but anybody who has taken a numerical analysis class understands the danger of storing them as floating-point numbers. GnuCash doesn't do that; instead, these numbers are stored as scaled integers in the GncNumeric class. Here is the utility function I bashed together to create such values from the (text) floating-point values output by QuickBooks:

    SCALE = 1000
    def GCVal(value):
        dollars, cents = map(int, value.split('.'))
        ival = dollars*SCALE
        if value[0] != '-':
            ival += cents*(SCALE/100)
        else:
            ival -= cents*(SCALE/100)
        return gnucash.GncNumeric(ival, SCALE)

With that in place, creating a split is a matter of instantiating a Split object, filling in the relevant information, and attaching it to the transaction:

    split = gnucash.Split(book)
    split.SetValue(GCVal(entry['Amount']))
    split.SetAccount(LookupAccount(entry['Account']))
    split.SetMemo(entry['Memo'])
    split.SetParent(trans)

Note that, unusually, splits do not have BeginEdit() and CommitEdit() methods.

One final complication is that, in an existing company file, most of the transactions are likely to be marked "reconciled"; that is information that should not be lost. GnuCash stores this information in the splits rather than in the transaction object. Unfortunately, this functionality isn't available in the high-level interface, so setting the flag (to either "y" or "n") requires going low:

    gnucash_core_c.xaccSplitSetReconcile(split.get_instance(), reconciled)

Once all of the splits are in place for a transaction, a call to CommitEdit() completes the job.

Next steps

These two scripts will yield a mostly complete GnuCash file, with the omissions described above, of course. A good confidence-building measure at this point is to generate some reports in GnuCash and verify that they match what QuickBooks says. In my case, an obvious next step is to toss the scripts used with the painful QuickBooks data import process and write new ones to push company data directly into the GnuCash file. With the tools described above, that should not be that hard to do.

These scripts are available under the GPL; they can be cloned from the repository at git://git.lwn.net/qb-escape.git. As the process of investigating accounting systems continues, this repository will likely accumulate more import scripts. Stay tuned.


to post comments

Escape from QuickBooks (with data in hand)

Posted Aug 7, 2017 22:03 UTC (Mon) by cpitrat (subscriber, #116459) [Link] (1 responses)

I guess to increase the likelihood of this article helping people who have the same need, it would make sense to not make it limited to LWN subscribers.

Escape from QuickBooks (with data in hand)

Posted Aug 7, 2017 22:21 UTC (Mon) by Beolach (guest, #77384) [Link]

All LWN articles are made public after 1 week.

Escape from QuickBooks (with data in hand)

Posted Aug 8, 2017 0:23 UTC (Tue) by gerdesj (subscriber, #5446) [Link] (1 responses)

My company escaped from Sage about a year ago. It is extremely liberating and worth persevering at. I no longer have to kick someone out to get a license and the PostgreSQL back-end we use is rather more efficient for multi user access than the shitty text files of the bottom end Sage offering. Our new system is not perfect by any means but can only improve as we add stuff to it. It already allows everyone in the firm to use it rather than the select few that licensing allows. I can point pgadmin and jdbc at it and mess around as I see fit (read only!)

It probably isn't for everyone - https://www.uzerp.com/ and https://github.com/uzerpllp/uzerp - but might be of interest to someone. It is UK focused but supports multi currency. It is really a ERP but we are are services company and it works very nicely for us. To cut a very long story short, the original sponsor is an accountant who set up a factory and decided to develop his own system and hired a programmer who has since retired. The current dev inherited a bit of a mess from his predecessor and has spent the last three years or so battering it into some sort of order. There's a lot more to do but it is extremely functional.

uzERP runs the show for a few SMEs in the UK from manufacturing to services, that we know of. The source is GPL3 and PHP with a PostgreSQL back-end.

Feel free to fork and crack on ...

Escape from QuickBooks (with data in hand)

Posted Dec 6, 2017 12:51 UTC (Wed) by philtrick (subscriber, #58080) [Link]

Thanks for this.

Have been looking for an alternative to OpenERP 6 (haven't upgraded due to removal of features from the free version), and the stock and manufacturing of other systems aren't that great.

Will have to give this a try..

Escape from QuickBooks (with data in hand)

Posted Aug 8, 2017 1:12 UTC (Tue) by Cyberax (✭ supporter ✭, #52523) [Link] (2 responses)

FWIW, QuickBooks has an API that allows you to connect to a running QB instance through a REST/XML API and introspect its database. It's fairly comprehensive and it can access values like the current balances that are difficult to obtain otherwise.

In one of my previous jobs, I built a data converter that used it to pull data into another accounting system.

Escape from QuickBooks (with data in hand)

Posted Aug 8, 2017 2:26 UTC (Tue) by ringerc (subscriber, #3071) [Link] (1 responses)

I had similar issues with MYOB, but found that (at least at the time) their ODBC driver and API access is only available if you're signed on to the MYOB Developer program. And they get to tell you if they don't like what you're doing with it.

It's also read-only except for specially authorised devs, so useful for export and reporting but not integration.

Sigh.

Escape from QuickBooks (with data in hand)

Posted Aug 8, 2017 11:19 UTC (Tue) by timrichardson (subscriber, #72836) [Link]

MYOB ODBC is free now. It's good enough for data conversion. It's well documented.

Escape from QuickBooks (with data in hand)

Posted Aug 8, 2017 7:00 UTC (Tue) by smurf (subscriber, #17840) [Link]

You can obtain the starting balances for an account by taking the final balance and then subtracting all the transactions in that account. A bit involved but hardly rocket science.

Splits obviously cannot have a commit method. That makes no sense. You can only commit the whole transaction, and then only when the splits sum up to zero. Otherwise Gnucash will "helpfully" credit the balance to a cure annoying "Imbalance-USD" account. (Disclaimer: that's what the UI does; I suspect the Python interface does the same thing.)

Distributions do enable database integration, though the process to actually connect to one is anything but straightforward. Still, it may be a good idea to use that because one can then run SQL statements on the raw data, which tends to be faster than starting up Gnucash itself and reading the whole account history. Note though that Gnucash still is not multiuser capable just because you're using a database back-end; it has no way to refresh the in-memory set of transactions as it doesn't store the change log in the database. (At least it *has* a change log.)

Escape from QuickBooks (with data in hand)

Posted Aug 11, 2017 17:44 UTC (Fri) by diederich (subscriber, #26007) [Link]

FYI: https://metacpan.org/release/Finance-IIF seems to be a thing.

GnuCash vs other alternatives

Posted Aug 13, 2017 12:46 UTC (Sun) by jnareb (subscriber, #46500) [Link] (1 responses)

I guess that GnuCash was chosen for now, instead of other tool or accounting data format (like e.g. http://plaintextaccounting.org) because it can generate reports that you can compare with QuickBooks one. Do I understand this correctly?

GnuCash vs other alternatives

Posted Aug 13, 2017 13:04 UTC (Sun) by corbet (editor, #1) [Link]

That, and because I'm familiar with it through use for personal finance. It's just the starting point, no more.

Escape from QuickBooks (with data in hand)

Posted Aug 20, 2017 0:11 UTC (Sun) by njs (subscriber, #40338) [Link] (1 responses)

> the utility function I bashed together to create such values from the (text) floating-point values

This is why python has built-in support for exact decimal calculations :-)

    import decimal
    # Disable rounding on decimal arithmetic
    # (Not really an issue b/c the only operation is multiplying by 1000, which never
    # needs to round, but paranoia is cheap.)
    decimal.getcontext().traps[decimal.Inexact] = True

    SCALE = 1000
    def GCVal(value):
        scaled = decimal.Decimal(value) * SCALE
        assert int(scaled) == scaled
        return gnucash.GncNumeric(int(scaled), SCALE)

Escape from QuickBooks (with data in hand)

Posted Sep 24, 2017 0:34 UTC (Sun) by bsdimp (guest, #18082) [Link]

There's three bugs that I found in this when doing my conversion from my 10-year-old collection of quickbooks data for my on-again, off-again consulting business....

(1) Credit Card accounts are exported as CCARD in the iif file. These weren't handled by qb_iif_to_gc since they weren't in the table. The fix is trivial.
(2) QuickBooks mac 2007 exports values larger than $999.99 with commas. Fix GCVal to remove commas.
(3) Related, fix termination case to test for the string '0.00' rather than doing the float conversion.

I have fixes for all these issues (though I had to hand-edit the csv files to remove the extra headers so qb_trans_to_gc wouldn't get confused. It would be nice if it filtered all that, but I gave up on hacking that together. It was easier to hack 10 files than to write code to cope. :/. I'll send them to the author of the article since I can't create a pull request since the git repo isn't on github...

Still, don't count this as complaining. This stuff is awesome. While I still need to verify that all the data was transferred into gnucash correctly and the P&L and Balance Sheet reports match, the initial scan of the data looks like it's there correctly.

Warner

Escape from QuickBooks (with data in hand)

Posted Oct 6, 2020 15:57 UTC (Tue) by jason.s (guest, #142392) [Link] (4 responses)

I just spent the past few days using these wonderful scripts to move all my books over to GnuCash 4.2 from QuickBooks Pro 2017, and to return the favor to the open source community, I thought I might help with a simple set of steps, updated for use in 2020:

Escape from QuickBooks to GnuCash (with data in hand), in simple steps (moving one company's book):
***The following was done moving from QB on Windows to GnuCash on MacOS***

Export your QuickBooks data:
1. Open QuickBooks and the Chart of Accounts
2. Check "Include inactive" at the bottom to show all inactive/hidden accounts
3. These scripts require that the accounts all have different names. Edit all accounts to be this way (double check subaccounts that may have the same name as other subaccounts). You can add numbers to the front of each to make them all uniquely named.
4. Remove forward slashes / from all account names (the scripts tripped up on this).
5. Export your Chart of Accounts and lists. Go to File > Utilities > Export > Lists to IIF Files... Not sure if the scripts can support all lists, but I believe it worked when I checked Chart of Accounts, Customer List, Vendor List, and Other Names List. Click OK and save the IIF file somewhere.
6. Determine when the EARLIEST transaction entry was ever made. If you don't know which account has the first transaction of all time, come up with a date that is definitely before when you started using QuickBooks.
7. Export all your transactions for all accounts of this company/book. Go to Edit > Find... Select the Advanced tab at the top. Under Choose Filter, scroll down and select Date. Immediately to the right make sure All is selected in the dropdown menu and specify the From and To dates with From being the date you determined in the previous step (before the first transaction) and To being today's date.
8. Click the Find button at the top right. In the resulting list below, scroll down to the very bottom to make sure that the earliest transactions are listed. If you believe all transactions are shown, click on the Export... button on the right. In the Export dialog, select "Create a comma separated values (.csv) file". Click Export below and save the CSV file where you saved the IIF file.
9. Copy these two exported files to your other computer with GnuCash (not necessary if you're using GnuCash on the same computer as QB).

Import your data into GnuCash:
10. On the computer with GnuCash, either use GIT to clone the import scripts offered on this page (if you understand GIT) from git://git.lwn.net/qb-escape.git or manually download both qb_iif_to_gc (https://lwn.net/Articles/730030/) and qb_trans_to_gc (https://lwn.net/Articles/730031/) to a folder for doing this import work.
11. Install Python via MacPorts and the GnuCash Python bindings. Go to https://wiki.gnucash.org/wiki/Python_Bindings and follow the installation steps (I did this for Mac OS X).
12. Note that if you used Homebrew to install Python before, MacPorts will install another set of them (note the directory where the MacPorts Python is). (Probably in /opt/local/bin/)
13. I was only able to get the scripts working with Python 3.6. Unfortunately, this requires updating some of the script code to work with the new Python version. Open the two scripts up in your preferred code editor (or even TextEdit/Notepad). Update all print/except commands to have round brackets (). For example:

print 'Account %s already exists' % (name)
should be:
print('Account %s already exists' % (name))

except IOError, e:
should be:
except (IOError, e):

In qb_trans_to_gc, update the following:

Line 32: return gnucash.GncNumeric(ival, SCALE)
Should be:
return gnucash.GncNumeric(int(ival), SCALE)

Under line 98: split.SetValue(GCVal(entry['Amount']))
Add
split.SetAmount(GCVal(entry['Amount']))

(We need to SetValue AND SetAmount)

Finally, for all instances of: entry = reader.next()
Change them to:
entry = next(reader)

14. It didn't work for me, but on Line 154, you can try changing the currency that should be used for this book.
15. Open GnuCash and create a new file by going to File > New. Select the least amount of accounts to create (I chose "A Simple Checkbook") that you can delete later on after importing in order to create the new file. Save the new book.
16. Quit GnuCash (this is important - the scripts will not work if GnuCash is running at the same time).
17. Open a terminal and run:
export PYTHONPATH=$PYTHONPATH:/opt/local/lib/python3.6/site-packages
18. Import the Chart of Accounts and Lists by running:
/opt/local/bin/python3.6 ~/Documents/GnuCash/qb-escape/qb_iif_to_gc ~/Documents/GnuCash/qb-escape/listexports.IIF ~/Documents/GnuCash/<YOUR GNUCASH FILENAME>.gnucash
19. Import your transactions by running:
/opt/local/bin/python3.6 ~/Documents/GnuCash/qb-escape/qb_trans_to_gc ~/Documents/GnuCash/qb-escape/exportedtransactions.CSV ~/Documents/GnuCash/<YOUR GNUCASH FILENAME>.gnucash
20. Run GnuCash. You should see all your accounts and transactions if everything worked! You can now delete all the extra .gnucash and log files generated by the scripts (keep the original .gnucash file you created). Enjoy GnuCash!

Escape from QuickBooks (with data in hand)

Posted Jan 18, 2021 15:56 UTC (Mon) by raygor (guest, #144248) [Link] (3 responses)

@Jonathan Corbet & Jason.s -

I seem to have missed some package dependency following your (and OP's) instructions. Which packages are iif and remap loaded from?

import iif
import remap

python3 qb_iif_to_gc.py -c -r ~/Desktop/2021-01\ foo.iif
Traceback (most recent call last):
File "qb_iif_to_gc.py", line 16, in <module>
import iif
ModuleNotFoundError: No module named 'iif'

Escape from QuickBooks (with data in hand)

Posted Jan 18, 2021 16:12 UTC (Mon) by corbet (editor, #1) [Link] (1 responses)

Those modules are in the repository with the rest of the code...

Escape from QuickBooks (with data in hand)

Posted Jan 18, 2021 20:09 UTC (Mon) by raygor (guest, #144248) [Link]

Thank you! I (re)discovered the git://git.lwn.net/qb-escape.git link 10 minutes after I hit submit.. :-/

Additional request for clarity, please - can you share an example of how you used the remap.py map file?

I am hopeful that this will help with QB losing the hierarchy of e.g.

Liabilities -> Credit Cards -> Card1
Liabilities -> Accounts Payable-> AP

Versus the current import where the middle tier is lost and everything is flattened under e.g. Liabilities.

Liabilities->Card1
Liabilities->AP

Thank you for publishing these scripts!

Escape from QuickBooks (with data in hand)

Posted May 8, 2022 2:26 UTC (Sun) by Izwebusr (guest, #158409) [Link]

Hi:

Thank you very much for publishing these scripts.

I am using these to migrate from QB to Gnucash. I have about 111000 transactions, over 22 years.

I have exported the lists and transactions from QB. I have also installed Python and the scripts. However, the scripts produce an error because I am stuck on how to install the Python Bindings. I do not know what needs to be done to install them. This documentations page:

https://wiki.gnucash.org/wiki/Python_Bindings#How_to_use_...

is not too helpful. Or, at the least, not easy to understand for me.

Is there any documentation someone can point me to?

Also, would it be a good idea to try to find a consultant to give me a hand with this?

Thanks!

Escape from QuickBooks (with data in hand)

Posted May 1, 2021 13:44 UTC (Sat) by erikmack@gmail.com (guest, #152008) [Link] (2 responses)

Thanks for this great article and these scripts. I have succeeded in importing data to GnuCash for my nonprofit.

The customizations I required I've pushed to GitHub, in case someone else finds them useful: https://github.com/erikmack/qb-escape

The customizations include:
- Support python 3
- Open the file in the new way
- Support account parameters for Placeholder, Hidden, Description, and Code
- Match splits to accounts by account code not name

My organization uses account codes so it's useful to import them and use them during the import.

Thanks again!

Escape from QuickBooks (with data in hand)

Posted Oct 5, 2021 14:12 UTC (Tue) by pyz01 (guest, #154562) [Link] (1 responses)

All -- not sure if this will help -- but this was taken from the QB site. It shows how to export specific data from QB directly to CSV:

Export CSV files
You can export a list as a CSV file if you don’t have MS Excel installed on your computer or if you want to view and edit your data using a different format.

Customers and Vendors
Open the Customer/Vendor Center.
Select the Excel drop-down, then choose:
Export Customer/Vendor list if you want to export customer/vendor data such as name, balances and contact information.
Export Transactions if you want to export transactions (either by name or transaction type).
In the Export window, choose Create a comma separated values (.csv) file.
Select Export.
Assign a file name, then choose the location where you want to save the file.
Locate, open, and edit the file as needed.

Items
Go to the Lists menu, then select Item List.
Select the Excel drop-down, then choose Export all Items.
In the Export window, choose Create a comma separated values (.csv) file.
Select Export.
Assign a file name, then choose the location where you want to save the file.
Locate, open, and edit the file as needed.

Reports
Open the report.
Select the Excel drop-down at the top of the report.
Select Create New Worksheet.
On the Send Report to Excel window, select Create a comma separated values (.csv) file.
Select Export.
Assign a file name, then choose the location where you want to save the file.
Locate, open, and edit the file as needed.

Have not tried these yet -- but I am going to attempt to this weekend to see how far I can get in exporting QBooks data to GNUCash directly using CSV files. Will let you know if I am successful.

Escape from QuickBooks (with data in hand)

Posted Mar 7, 2022 2:26 UTC (Mon) by lragan (guest, #157284) [Link]

My book in QuickBooks is not that large, so my method may not work for all, but here goes. I use GnuCash 2.6.19 in linux.
I was hanging on to QuickBooks 2008, which is not subscription. Giving up my Windows 7 machine, I discovered that I was, as I suspected, riding a dead horse. (I have switched to Linux for all but tax prep software. I keep a Windows 10 machine for that purpose, and occasional interaction with something that someone sends me, but for the most part, like a housecleaning service, I don't do Windows!) But, I was able to write out an account list to a CSV file. After fumbling around a bit in the import function of GnuCash, I decided to follow their format precisely. It is revealed in the import process as a "custom" import option. Not understanding the symbols that make up the command, I simply took note of the field names.
Then, using a spreadsheet program, I rearranged the CSV file into the format of the import option, adding blank columns where needed, using their field names in the first row.
After importing, it was necessary to enter the balances from my CSV file (GnuCash, understandably, does not import the balances). This was done by a series of simple cut and paste operations. It was then necessary to edit the accounts into the hierarchy that I needed. I took this opportunity to delete accounts that I no longer used or needed (one can always add an account using GnuCash if necessary).
When done, the reports work to show balance sheet and income statement. I have not used the others yet, but suspect they work, too. I entered one month's data (January 2022) taking off from the year end of QuickBooks in 2021, and all reconciles nicely. When one enters the balance for each account, GnuCash puts the compensating balance into an "Unbalance" account. If all is done correctly, this will go go zero when the last data is entered.
This is, I admit, a "brute force" approach, but for me, I feel certain that is was less work than writing code to do the job. For a more complicated business than mine, that might not be the case. I can now retire my ancient Windows 7 machine and let QuickBooks rest in peace...
Color me happy with GnuCash, and grateful for all who have contributed to it.

Escape from QuickBooks (with data in hand)

Posted Mar 22, 2023 15:41 UTC (Wed) by vivekgani (guest, #164240) [Link]

I've recently made some improvements to both the instructions and scripts based on my experiences with quickbooks 2022 & 2023 to migrate to GnuCash in https://github.com/erikmack/qb-escape .

Notably, I found the exported data in the 'find all' approach in the article difficult to work with and the script was causing lots of imbalances (split and account values were sometimes mixed, relying on just the 'amount' value didn't work in many cases). Instead switched to an approach that uses the 'Journal' instead which had more consistent data.

Thanks to Jonathan Corbet, and the comments by jason.s and erikmack on instructions and setting up a github repo.


Copyright © 2017, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds