Показать сообщение отдельно
Старый 20.01.2021, 17:30   #42  
kair84 is offline
kair84
Участник
 
47 / 58 (2) ++++
Регистрация: 15.04.2010
Адрес: Belarus
Цитата:
Сообщение от trud Посмотреть сообщение
Спасибо что поделились. Еще как вариант можно наверное сделать отдельную табличку(Статус, Результирующий файл), запускать эту операцию в пакете и приатачивать файл к этой табличке по завершению. Пользователь соответсвенно будет скачивать файл когда он сформируется и может вообще закрыть браузер
Конечно, можно развивать идею на свой вкус и цвет.

Для моих целей этого вполне достаточно, я всего лишь хотел восстановить возможность взаимодействия с пользователем после выполнения операции в отдельной сессии.

Доработал пример для корректной работы в пакетном режиме
X++:
// This is a framework class. Customizing this class may cause problems with future upgrades to the software.
class Test_RunbaseBatch extends RunBaseBatch
{
    // Packed variables
    str             csvFileContent;
    Email           email2Send;

    #define.CurrentVersion(1)
    #localmacro.CurrentList
        csvFileContent,
        email2Send
    #endmacro

    public boolean getFromDialog()
    {
        boolean ret;

        ret = super();

        email2Send = SysUserInfo::getUserEmail(curUserId());

        return ret;
    }

    public container pack()
    {
        return [#CurrentVersion,#CurrentList];
    }

    public void run()
    {
        info("run");

        if (! this.validate())
            throw error("");

        commaStreamIo iO = commaStreamIo::constructForWrite();

        container header = ["Num"];
        iO.writeExp(header);

        int i;
        for (i=1; i<=660; i++)
        {
            iO.write(i);

            //sleep(1000); //Over 10 min.
            sleep(100);
        }

        System.IO.Stream stream = iO.getStream();
        stream.Position = 0;
        System.IO.StreamReader reader = new System.IO.StreamReader(stream);
        csvFileContent = reader.ReadToEnd();

        if (this.isInBatch())
        {
            this.runAfterOperation();
        }

    }

    public void runAfterOperation()
    {
        info("runAfterOperation");

        Filename filename = "file.csv";
        System.Byte[] byteArray =  System.Text.Encoding::Unicode.GetBytes(csvFileContent);
        System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
        stream.Position = 0;

        if (this.isInBatch())
        {
            if (SysEmailDistributor::validateEmail(email2Send))
            {
                SysMailerMessageBuilder messageBuilder = new SysMailerMessageBuilder();
                messageBuilder.setFrom(email2Send,"@SYS115063")
                              .addTo(email2Send)
                              .setPriority(1)
                              .setSubject(this.caption())
                              .setBody(this.caption())
                              .addAttachment(stream, fileName);
                SysMailerFactory::sendNonInteractive(messageBuilder.getMessage());
                info(strFmt("CSV file %1 Sent to user on e-mail %2",filename,email2Send));

            }
        }
        else
        {
            File::SendFileToUser(stream, fileName);
            info(strFmt("CSV file %1 Sent to user",filename));
        }

    
    }

    public boolean runsImpersonated()
    {
        return true;
    }

    public boolean unpack(container packedClass)
    {
        Version version = RunBase::getVersion(packedClass);
    ;
        switch (version)
        {
            case #CurrentVersion:
                [version,#CurrentList] = packedClass;
                break;
            default:
                return false;
        }

        return true;
    }

    public boolean validate(Object _calledFrom = null)
    {
        if (false)
            return checkFailed("");

        return true;
    }

    static ClassDescription description()
    {
        return "Test RunBase";
    }

    static Test_RunbaseBatch construct()
    {
        return new Test_RunbaseBatch();
    }

    static void main(Args args)
    {
        Test_RunbaseBatch    runBase;

        runBase = Test_RunbaseBatch::construct();

        if (runBase.prompt())
        {
            runBase.runOperation();

            if (!runBase.batchInfo().parmBatchExecute())
            {
                runBase.runAfterOperation();
            }
        }

    }

    protected boolean canRunInNewSession()
    {
        return true;
    }

}