X++ to read data from a spreadsheet

Often there are times when data needs to be ready from a spreadsheet.  An easy way to handle this is to copy/paste from the spreadsheet to a text file (which will be tab delimited by default) and then use this code (modified as needed) to read that data and do whatever is needed with it.  It includes a dialog to select the file, if the file has a header row, and a progress bar displayed to the user.

static void importScriptTemplate(Args _args)
{
    #File
    TextIo                  io;
    container               c;
    FileIOPermission        permission;
    Filename                filename;
    Dialog                  dialog;
    DialogField             filenameField;
    DialogField             headerRowField;
    container               filetypes = [#AllFilesType, #AllFiles];
    boolean                 containsHeaderRow;


    SysOperationProgress    progress;
    int                     i;
    int                     total;

    dialog = new Dialog("Select file to load");
    filenameField = Dialog.addField(extendedTypeStr(FilenameOpen));
    headerRowField = dialog.addFieldValue(extendedTypeStr(NoYesId), NoYes::Yes, "Contains header row");
    dialog.filenameLookupTitle("Select file to load");
    dialog.filenameLookupFilter(filetypes);
    if (dialog.run())
    {
        filename = filenameField.value();
        containsHeaderRow = headerRowField.value();

        permission = new FileIOPermission(Filename, #io_read);
        permission.assert();

        io = new TextIo(Filename, #io_read);
        if (!io)
        {
            throw error("Error reading file");
        }
        io.inFieldDelimiter('\t');
        io.inRecordDelimiter(#delimiterCRLF);

        //Read through file once to determine number of lines (this is quick if no processing is done per line)
        while (io.status() == IO_Status::Ok)
        {
            c = io.read();
            if (io.status() != IO_Status::Ok)
            {
                break;
            }
            total++;
        }

        //Set up progress bar
        progress = new SysOperationProgress();
        progress.setAnimation("104.avi");
        progress.setCaption("Reading file");
        progress.setTotal(total);

        io = new TextIo(Filename, #io_read);
        if (!io)
        {
            throw error("Error reading file");
        }
        io.inFieldDelimiter('\t');
        io.inRecordDelimiter(#delimiterCRLF);

        //Now process the file
        ttsBegin;
        while (io.status() == IO_Status::Ok)
        {
            progress.incCount();
            i++;
            progress.setText(strFmt("Reading line %1 of %2", i, total));

            c = io.read();
            if (i == 1 && containsHeaderRow) //burn header row
            {
                c = io.read();
            }
            if (io.status() != IO_Status::Ok)
            {
                break;
            }

        }
        ttsCommit;

        CodeAccessPermission::revertAssert();
    }
    info("Finished");
}

Comments

Popular posts from this blog

Posting Purchase Order Invoices via X++

Using X++ to get a list of files in a directory

Split a production order with X++