jueves, 15 de septiembre de 2011

Sending a plain text file to the Ax server tier

Seems simple enough. The only thing we want to avoid here however is having to use special file I/O permissions writing files to a server directory. Also I couldn't find any special file upload form control but Santosh Singh got there first using the WinApi class.

First lets create a button on the form and override the usual clicked() event:
void clicked()
{
    str                 fileName;
    FileNameFilter      filter      = ['*.txt', '*'];
    BinData             binData     = new BinData();
    Args                args        = new Args();
    ;
    
    super();
    
    // Obtain the path to the file on the client
    fileName = WinApi::getOpenFileName(element.hWnd(), filter, '', 'Upload import file');
    if (binData.loadFile(fileName))
    {
        args.object(binData);
        EVE_CONFileImporter::mainOnServer(args);
    }
}
In the code above we probably should have used the AsciiIo class instead of BinData, for example. That may bite us later as it would simplify things.

We're now to parse the file within a class method, running on the server tier. New lines are supposed to be separated by '\n' but we can use any character to split our text data:
void importErrors(BinData _binData)
{
    TextBuffer  textBuffer  = new TextBuffer();
    str         line;
    int         posEnd = 0, posStart = 0;
    int         nlLen, bufferSize;
    // '\r\n' - Windows : '\n' - *nix : ',' - CSV : '\t' - Tabbed
    #define.newLine('\n') 
    ;
    
    if (!_binData || _binData.size() == 0)
    {
        return false;
    }

    // One Über string
    textBuffer.setText(_binData.getStrData());

    // Super-Size me
    bufferSize      = textBuffer.size();
    nlLen           = strlen(#newLine);

    // Parse the file line by line
    while (posEnd < bufferSize)
    {
        // When you specify the start position for substring, use 1 for the first character in content. MSDN example
        posStart    = (posStart == 0 ? posStart + 1 : posEnd + nlLen);
        textBuffer.find(#newLine,posStart);
        posEnd      = textBuffer.matchPos();
        if (posEnd == 0)
        {   // EOF
            posEnd  = bufferSize;
        }
        line = textBuffer.subStr(posStart, posEnd - posStart - nlLen - 1);
        if (strlen(line) > 0)
        {
            info(line);
        }
    }
}
I had a problem with trimming the end control character from the end of the line so do test the above code for yourself in case you are losing an important number digit from the end of everyone's newly imported pay check!

No hay comentarios:

Publicar un comentario