Working with XMLScript in Bartender 9.4

There are a couple of gotchas when attempting to automate BarTender using XMLScript against an SQL database. Here’s the example from the documentation:

<?xml version="1.0" encoding="utf-8"?>
<XMLScript Version="2.0">
  <Command Name="Job1">
    <Print>
      <Format>c:\labels\Label1.btw</Format>
      <RecordSet Name="SQL_OLEDB" Type="btOLEDB">
        <UserID>Admin</UserID>
        <Password>seagull</Password>
        <SQLStatement>SELECT ProductName FROM Products WHERE Supplier = 'Exotic Liquids'</SQLStatement>
      </RecordSet>
    </Print>
  </Command>
</XMLScript>
  • The sql you use in XMLScript needs to match the sql that BarTender uses in the database setup of the label format. For instance, if BarTender wants to write the sql like this “dbo”.”TableName”.”FieldName” then the SQLStatement node of your XMLScript has to follow the same format. FieldName won’t work and neither will TableName.FieldName or even dbo.TableName.FieldName. The quotes are aparently important for BarTender to match the fields it has in the label format with the fields that come back from sql. The example will lead you astray here.
  • The Name attribute of the RecordSet node needs to be the name of the sql database you are connecting to. The docs state that Name is the “Name of the record set.” which is not exactly clear and again, the sample is not much help.
  • The UserID and Password are not necessary if you set the label format to Use Windows NT Integrated security.
  • As far as I can tell there is no way to set the Server you want BarTender to query using XMLScript.
  • You want to set the Use Client Cursor option in Database Setup Options of the label format to true. If not, the sql sent to the server is a series of unreadable prepared statements which as far as I can tell don’t actually evaluate to the query you set up in SQLStatement node.
  • You have to make sure the print dialog Selected Records field reads 1… If you do a print preview while designing the label format, the program will helpfully populate this field with 1-8 if you have 8 records you are previewing. The problem is that this is then saved with the label format! When you issue an XMLScript SQLStatement that returns 20 records, only records 1-8 will print!
Posted in BarTender | Comments Off

Write Conflict with Access as front end to MySQL database

There are all sorts of things that can cause a write conflict when using Access with tables linked to a back end database, but here’s one I hadn’t seen before: A date or datetime column with default values outside Access’ acceptable range. Specifically, the Zen Cart schema includes some fields with defaults of 0001-01-01! My client changed the defaults to 1901-01-01 and reports that Zen Cart continues to work ok, but your mileage may vary.

Posted in Access, MySQL | Comments Off

Making BarTender an optional component

I need to add bar code printing to an existing application, and the component we chose to use is BarTender (9.3 SR3). The problem is that BarTender is only installed on a few of the workstations running the application. If we add a reference to the Seagull.BarTender.Print assembly in the GAC, the majority of our installed instances won’t run. So what’s the solution?

1. Copy the following files from the GAC into the project folder (This assumes you have BarTender installed on the development machine). See here for instructions on copying from the GAC. I prefer the last option.  There are quite a few BarTender dlls, but these appear to be the necessary ones.

Seagull.BarTender.Print.dll (GAC_32 folder)
Seagull.Interop.dll (GAC_32 folder)
Interop.BarTender.dll (GAC_MSIL folder)

2.  Add the files to the project and set their properties:

Build Action = None
Copy To Output Directory = Copy always

3. Add a reference to the Seagull.BarTender.Print.dll file that was copied to the project. Use the Browse tab of the Add Reference dialog, not the .NET tab! The Copy Local property can be left False. The project should compile now even if it uses BarTender code.

4. At this point, if the project targets Any CPU you will get an error when building:

Could not load file or assembly ‘Seagull.BarTender.Print, Version=9.40.3.1, Culture=neutral, PublicKeyToken=109ff779a1b4cbc7′ or one of its dependencies. An attempt was made to load a program with an incorrect format.

The project has to target x86. Sorry.

5. Wrap any calls to the BarTender print engine in Try/Catch blocks. If BarTender is not installed, any attempt to actually use the print engine will throw an error. Here is a very simple example that just starts up the print engine and then stops it again:

Dim engine As Seagull.BarTender.Print.Engine
Try
  engine = New Seagull.BarTender.Print.Engine(True)
Catch ex As Exception
  MessageBox.Show(ex.Message)
Finally
  If Not engine Is Nothing Then
    engine.Stop(Seagull.BarTender.Print.SaveOptions.DoNotSaveChanges)
  End If
End Try

6.  Uninstall BarTender and make sure everything degrades nicely.

Note: If the Interop dlls are not included, the error when creating a new Engine will be a FileNotFoundException for one of the Interop files. Also, If you don’t include both Interop files, and you run the code above, you will also get an error when the application is closed:

System.IO.FileNotFoundException was unhandled
Message=”Could not load file or assembly ‘Interop.BarTender, Version=9.40.3.1, Culture=neutral, PublicKeyToken=109ff779a1b4cbc7′ or one of its dependencies. The system cannot find the file specified.”
Source=”Seagull.BarTender.Print”
StackTrace:
at Seagull.BarTender.Print.Engine.Dispose(Boolean bDisposeManaged)
at Seagull.BarTender.Print.Engine.Finalize()

The nasty thing about this is that you can’t catch the error in the application, so Windows does it:

XXXX has stopped working. Windows is checking for a solution to the problem…

Posted in BarTender, VB.net, VB.net 3.5, WinForms | Comments Off

Upgrading settings in the ProgramData folder

One of my applications has several small xml files saved in the ProgramData folder that contain configuration information.  This works nicely, but when a new version of the application is installed, I need to bring these files forward so the user doesn’t lose their settings.  It seems like there must be a better way to do this, but the following looks through previous folder versions for the files.

The folder path follows the format C:\ProgramData\Company Name\Program Name\1.0.0.1

Dim ds As New DataSet
Dim a As String = My.Computer.FileSystem.SpecialDirectories.AllUsersApplicationData
Dim b As String = "\Job.xml"
If IO.File.Exists(a &amp; b) Then
    ds.ReadXml(a &amp; b)
Else
    Dim di As DirectoryInfo = Directory.GetParent(a)
    Dim dirs = di.GetDirectories.OrderByDescending(Function(f) f.FullName)
    For Each d As DirectoryInfo In dirs
        If d.FullName &lt;&gt; a Then
            If File.Exists(d.FullName &amp; b) Then
                ds.ReadXml(d.FullName &amp; b)
                Exit For
            End If
        End If
    Next
End If
Posted in VB.net, VB.net 3.5, WinForms | Comments Off