Monday, March 7, 2011

What's up with that 'Error executing code - AsciiIO object not initialized'?

Picture this:
You are working on a piece of X++ code, where creating a text file is involved.  Maybe you use the AsciiIO class, or maybe you use the TextIO class, the newer installment.  Maybe CommaIO/CommaTextIO is the class you use for creating comma-separated files with Ax.
Your code looks fine (of course it does :-) ).  But still you get this nasty error. 
You have set your permissions, you have initialized the file, set it ready for writing etc.  But still you keep getting this error, even though the code worked fine with other projects.

Error executing code - AsciiIO object not initialized

Tip: You might wanna take a look at the layer the code is executed, server or client.
The code might need to run on the client tier, as otherwise you will get the error message above.  So check you keywords in the declaration, the RunOn-property of the menu-item.
File handling on the server requires some precautions, take a look at the WinAPIServer class.

A short example on how to create a text file with Ax:

static void TextFileDemo(Args _args)
{   
    AsciiIO             tmpfile;
    Filename            tmpfilename;
    FileIOPermission    permission;
    #File
    ;
    tmpfilename = WinApi::getTempFilename(WinAPI::getTempPath(),'DEMO');

    permission = new FileIOPermission(tmpfilename,#IO_write);
    permission.assert();

    tmpfile = new AsciiIO(tmpfilename, #IO_write);

    if(tmpfile.status()==IO_Status::Ok)
    {
        tmpfile.outRecordDelimiter('\n');
        tmpfile.outFieldDelimiter(';');
    } else
    {
        return;
    }

    tmpfile.writeExp(['column1','column2','column3']);
    tmpfile = null;
    CodeAccessPermission::revertAssert();
}

5 comments:

  1. Whenever I write x++ code that needs to interact with the Filesystem, I always follow these steps:
    1) Build the filepath and name
    2) Run FileIOPermission on the path with appropriate action (read and/or write)
    3) Instantiate the io-object (asciio, commaio, textio, etc) with the filepath and name and action.
    4) check if the io-object is not null: if (!commaIO) return/throw

    ReplyDelete
  2. Hello Skaue,

    Number 4 is for sure a good one. After instantiating, check if the IO object is not null.
    Then later on during reading/writing check with the file status.

    Thanx for the reply.

    Regards,

    Willy.

    ReplyDelete
  3. Willy,

    I'm using UNC path: \\someFolder\someFile.csv

    I've tried to run my class on the server and on the client by changing the RunOn property for teh class. I keep getting the "commaTextIo object not initialized" error.

    Any ideas?

    Thanks.

    ReplyDelete
  4. Are you sure your class is running on the client tier? Are you using an menu-item to start it?
    Maybe you use a construct method, and here it is specified that the class should run on the server.

    Also: Do you have access to the folder? Read/Write access?

    And, literals:
    Be careful with using backslashes in your initialisation. Ax expects special characters with backslashes, and will not translate this to the start of a UNC pathname. So do this:
    filename=@'\\someFolder\someFile.csv';

    ReplyDelete
  5. I had the same problem, the code was correct. The file path and name were correct. Backslashes were
    escaped. The calls, the setup, everything was correct, except...

    When a new Class is created the RunOn property is set to "Called from" by
    default. Changing that to "Client" fixes the problem.

    ReplyDelete