sophieデータ出力機構マニュアル
last update: Tue, 13 Aug 2024 04:30:12 GMT ( 10 months ago )

        第2世代

        第2世代は、画面にインプリメントされた帳票系の開発後期に適用された方式で作られているものです。
        第1世代と違い、帳票のレイアウトや出力処理を変更したあとに画面自体を再読み込みすることなく印刷できることがメリットとなります。
        例)
         ・見積入力画面(見積書)

        • 記述例

          画面側
          ・fn.async.loadReport の呼び出し
          のみを記述します。
          ・printCntData 関数(件数取得)の定義
          ・printGetData 関数(データ取得)の定義
          ・printCnvData 関数(データ表示加工)の定義
          の定義はいりません。
          帳票RSD側
          ・レイアウト定義
          ・出力処理
          を記述します。

          • 画面側

            fn.async.loadReport
                  return fn.async.loadReport("hankan_estimate_ipt_print", {
            "hankan_estimate_ipt_print": {
            resources: {
            reg_no: reg_no
            },
            Lock: DispLock,
            onNextPage: function(cur, max) {
            DispLock.notify(fn.sync.getInfoMes(fn.fin("INFO.printing_x"), [ [cur, max].join('/') + ' ' ]));
            },
            page: "標準_縦",
            }
            }, {
            use: 'v1',
            prt_entry_no: reg_no,
            resources: {
            reg_no: reg_no
            },
            REPORT_MODE: report_mode,
            keep: FALSE,
            page: "標準_縦",
            title: title,
            // printing: FALSE,
            });
            printCntData
            定義なし
            printGetData
            定義なし
            printCnvData
            定義なし
          • 帳票RSD側

            PDFタイトルの加工
                    // 外からの定義の受け入れ
            $.extend(def, params);
            // 余白対応
            // param.page が本来、options.page はすべての帳票に対して1つしかない
            let page = params.page || options.page;
            let p_margin = fn.fin("Default.report_page." + page + ".margin");
            let d_left = 15 - +(p_margin.left.replace("mm", ""));
            let d_right = 15 - +(p_margin.right.replace("mm", ""));
            widSp = d_left + d_right;
            wid100per = wid100per + widSp;
            debugger;
            // title 変更
            let addStr = "(見積書)";
            options.title = options.title + addStr;

            // システム設定にファイル名用のコマンドがある場合のみ続行
            if (!fn.sync.hasValue(fn.fin("FILE_NM_COMMAND.estimate"))) return;
            // データからタイトル生成する場合ここで
            return getOneData().then((obj)=>{
            return fn.async.requireCommand(
            fn.fin("FILE_NM_COMMAND.estimate"),
            { execArgs: [{def: def, data: obj}] }
            ).then((title)=>{
            options.title = title;
            })['catch'](function(e) {
            // コマンドが見つからなかった場合やコマンドのエラーは無視
            console.log("ファイル名定義用のコマンドがないかタイトルが生成できませんでした。", e);
            });
            });
            レイアウトの定義(一部抜粋)
                    // --------------------------------------------------------------------------------- //
            // パートの定義 //
            // --------------------------------------------------------------------------------- //
            // EXCEL の 1行あたりのサイズを定義
            rpt.XLSH(drawPage.XLSH = XLSH);
            // 共通で利用するエリア(初期化もれを忘れずに)
            var area, area_name, area_size, area_opts;
            var pat = [];
            var line = [], lines;
            var hline, vline; // 罫線用
            var xposi = 0;
            // ----------------------------------------------- //
            // <ページヘッダー部分> //
            // ----------------------------------------------- //
            //drawPage.head = rpt.createShanaiReportHeader(pr, MODULE, TITLE, {
            // noborder: TRUE,
            // pagelabel: "全体頁数:",
            //});
            drawPage.head = rpt.createOutsideReportHeader(pr, MODULE, TITLE, true);
            // => パターン登録
            // ----------------------------------------------- //
            // <ページフッター定義> //
            // ----------------------------------------------- //
            drawPage.foot = rpt.createShanaiReportFooter(pr);
            // => パターン登録
            // ----------------------------------------------- //
            // (*) 描画領域は 横:0-180(mm) 縦:0-(XSLH): A4 210x297 - margin30
            // ----------------------------------------------- //
            // ----------------------------------------------- //
            // <ヘッダ部分>     //
            // ----------------------------------------------- //
            area = 'fix_head';
            area_name = 'page-content';
            area_size = '100% ' + (XLSH * 8);
            area_opts = {
            font: 'middle',
            };
            drawPage[area] = pr.createBlockPart(area_name, area_size, area_opts);
            pat = [];
            lines = [];
            // 1行目
            lines.push(line = []);
            line.push(["", 140],["見積No", 20],["=estimate_reg_no", 22, "right"]);
            lines.push(line = []);
            line.push(["=user_nm", 75, NULL, NULL, {"font-size": "12pt"}],["様", 10],["",55],["見積日", 20],["=estimate_date", 22, "right"]);
            lines.push(line = []);
            lines.push(line = []);
            line.push(["ご担当:", 14],["=tanto_nm", 25],["様", 5]);
            lines.push(line = []);
            line.push(["件名:", 14],["=subject", 150]);
            lines.push(line = []);
            line.push(["につきまして、下記の通り御見積り申し上げます。", 100]);
            lines.forEach(function(line, i) {
            SetLineNonBDR(pat, line, 0, i);
            });
            // 下行罫線
            pat.push(Line(0,2,85,2));
            drawPage[area].pattern(pat);
            // => パターン登録
            // ----------------------------------------------- //
            // <期限、金額エリア部分>    //
            // ----------------------------------------------- //
            area = 'total_area';
            area_name = 'total_area';
            area_size = '50% ' + (XLSH * 10);
            area_opts = {
            font: 'middle',
            border: '1px solid #444'
            };
            drawPage[area] = pr.createBlockPart(area_name, area_size, area_opts);
            pat = []; // 初期化
            lines = []; // 初期化
            lines.push(line = []);
            line.push(["納  期", 30], ["=nouki_nm", 40]);
            lines.push(line = []);
            line.push(["納入場所", 30], ["=ukewatashi.nm", 40]);
            lines.push(line = []);
            line.push(["有効期限", 30], ["=estimate_limit_date", 40]);
            lines.push(line = []);
            line.push(["御支払条件", 30], ["=cond_nm", 40]);
            lines.forEach(function(line, i) {
            SetLineNonBDR(pat, line, 0, (i+5));
            // 下行罫線
            pat.push(Line(0,(i+6),75,(i+6)));
            });
            lines = [];// 初期化
            // 合計金額行
            lines.push(line = []);
            line.push(["見積合計金額(税抜)", 40, NULL, NULL, { "font-size": "13px" }], ["=sum_gaku_exc_f", 40, "right", NULL, { "font-size": "13px" }]);
            lines.push(line = []);
            line.push(["消費税額(欄外明細)", 40, NULL, NULL, { "font-size": "13px" }], ["=sum_zei_gaku_f", 40, "right", NULL, { "font-size": "13px" }]);
            lines.push(line = []);
            line.push(["御見積合計金額(税込)", 40, NULL, NULL, { "font-size": "13px" }], ["=sum_gaku_inc_f", 40, "right", NULL, { "font-size": "13px" }]);
            lines.push(line = []);
            line.push(["", 80], ["=user_cd", 25, "center"]);
            // 4行目(20190903_白坂 適格請求書対応)
            lines.push(line = []);
            line.push(["=zei_box_str1", 140, NULL, NULL, {"fontSize":"8pt"}]);
            // 5行目(20190903_白坂 適格請求書対応) //税区分が3つ以上あったらこのフィールドを使う。(ほとんどないパターンかとは思うが…)
            lines.push(line = []);
            line.push(["=zei_box_str2", 140, NULL, NULL, {"fontSize":"8pt"}], ["", 23], ["通貨", 9, "center"],["=tsuka_cd", 10, "center"]);
            lines.forEach(function(line, i) {
            SetLineNonBDR(pat, line, 0, i+10);
            });
            // 下行罫線
            pat.push(Line(0, 14, 80, 14));
            drawPage[area].pattern(pat);
            // => パターン登録
            出力処理(部分抜粋)
                  // --------------------------------------------------------------------- //
            // 印刷実行処理        //
            // --------------------------------------------------------------------- //
            // (1) 集計ページ情報取得処理:aggregate => aggregate.result
            // (2) グループ集計処理処理 => aggregate.groups
            // (3) ページ数取得処理 => aggregate.groups.ALL.page_num
            // (4) ページごとの描画処理:drawPage
            }).then(function() {
            // (1) 集計ページ情報取得処理:aggregate => aggregate.result
            return aggregate();
            }).then(function() {
            // (3) ページ数取得処理 => aggregate.groups.ALL.page_num
            return getWholePageCount();
            }).then(function(wpc) {
            if (wpc == 0) {
            return putThrErr('INFO.no_data_for_report');
            }
            // ページ数が多いときの対応
            var printPage;
            var when = Promise.resolve();
            if(wpc > NOTIFY_PAGE_NUM) {
            when = when.then(function() {
            // 出力ページ数の制御
            return fn.async.openPrtPageRange(wpc, {
            mdl_kbn: "hankan",
            limit: NOTIFY_PAGE_NUM
            }).then(function(func) {
            // HybridPrint のオプションに強制セット
            printPage = pr.sheet.hp.options.printPage = func;
            wpc = printPage.pages.length;
            });
            });
            }
            // (4) ページごとの描画処理:drawPage
            fn.each(aggregate.groups, function(g_key, g_box) {
            // グループに関するページごとの描画
            if(g_key == 'ALL') return;
            for(var i = 0;i < g_box.page_num; i++) (function(page_i) {
            when = when.then(function() {
            return getPageData(g_box, page_i);
            }).then(function(a) {
            var ALL = aggregate.groups.ALL;
            return drawPage.call(pr, a, g_box, {
            page_idx: page_i,
            page_cnt: page_i + 1,
            page_num: g_box.page_num,
            pageALL_idx: drawPage.n,
            pageALL_cnt: drawPage.n + 1,
            pageALL_num: wpc,
            printPage: pr.sheet.hp.options.printPage
            });
            }).then(function(skip) {
            if(skip === TRUE) return;
            return new Promise(function(rsl) {
            setTimeout(rsl, 120); // Interval for loader
            });
            });
            })(i);
            });
            return when;
            });
            出力定義(drawPage:一部抜粋)
              // --------------------------------------------------------------------------------- //
            // 1ページごとの出力の定義 //
            // --------------------------------------------------------------------------------- //
            function drawPage(a, g_box, stat) {
            debugger;
            var pr = this;
            var XLSH = drawPage.XLSH;
            return Promise.resolve().then(function() {
            // 最初以外は次のページを作成
            if(drawPage.n) {
            pr.nextPage();
            }
            // 進捗状況のお知らせ
            if(isFunction(def.onNextPage)) {
            def.onNextPage.call(pr, drawPage.n += 1, stat.pageALL_num);
            }
            // var page_stat = fn.extend(TRUE, {}, {
            // head: g_box.head,
            // page: g_box.page[stat.page_idx],
            // stat: stat,
            // ALL: aggregate.groups.ALL
            // });
            var yposi = 0;
            // ヘッダーの描画
            pr.write(drawPage.head, '0 ' + yposi);
            yposi += XLSH * 4;
            var headObj = conv(g_box.head);
            // 宛先ヘッダーの描画
            if (stat.page_num == 1) {
            // 顧客名、番号
            pr.write(drawPage.fix_head, '0 ' + yposi, headObj);
            yposi += XLSH * 2;
            // 納期〜金額、送信者
            pr.write(drawPage.total_area, '0 ' + yposi, headObj);
            if (fn.fin("TANTO_IN_BOX.estimate") !== FALSE) {
            pr.write(drawPage.sent_by, wid100per / 2 + ' ' + yposi, headObj);
            pr.write(drawPage.stamp, '90 ' + XLSH * 15, headObj);
            yposi += XLSH * 16;
            } else {
            yposi += XLSH * 4;
            pr.write(drawPage.sent_by, wid100per / 2 + ' ' + yposi, headObj);
            yposi += XLSH * 12;
            }
            }
            // 表部分の描画
            // 表ヘッダー
            pr.write(drawPage.trow_head, '0 ' + yposi);
            yposi += XLSH * 2;
            (a || []).forEach(function(obj, i) {
            var kbn = obj.odr_kbn;
            var d_line = !fn.sync.hasValue(obj.draw_line) || obj.draw_line === TRUE;
            switch(kbn) {
            case "09": // 小計
            pr.write(drawPage.sum_s, '0 ' + yposi, obj);
            yposi += XLSH * 1;
            break;
            case "08": // 摘要
            // 余計な情報は除去する
            ["shohin.suryo_i", "shohin.tanka_i", "shohin.gaku_i"]
            .forEach(function(dbid, i) {
            var _dbid = dbid.split(".");
            delete obj[_dbid[0]][_dbid[1]];
            });
            var area = d_line ? drawPage.trow_body1_bdr: drawPage.trow_body1;
            pr.write(area, '0 ' + yposi, obj);
            yposi += XLSH * 1;
            break;
            default:
            var cd = obj.shohin.cd, nm = obj.shohin.nm, desc = obj.shohin.description;
            var _hasV = (v)=>fn.sync.hasValue(v);
            var _setV = (k,v)=>fn.sync.setVal(obj, k, v);
            // 3つともデータがある(3行表示)
            if (_hasV(cd) && _hasV(nm) && _hasV(desc)) {
            var area = d_line ? drawPage.trow_body3_bdr: drawPage.trow_body3;
            pr.write(area, '0 ' + yposi, obj);
            yposi += XLSH * 4;
            } else {
            var area = d_line ? drawPage.trow_body2_bdr: drawPage.trow_body2;
            // 2つデータがある(2行表示)保存場所をスライドする
            if (_hasV(cd) && _hasV(nm)) {
            _setV("shohin.nm", cd);
            _setV("shohin.description", nm);
            pr.write(area, '0 ' + yposi, obj);
            yposi += XLSH * 3;
            } else if (_hasV(cd) && _hasV(desc)) {
            _setV("shohin.nm", cd);
            _setV("shohin.description", desc);
            pr.write(area, '0 ' + yposi, obj);
            yposi += XLSH * 3;
            } else if (_hasV(nm) && _hasV(desc)) {
            _setV("shohin.nm", nm);
            _setV("shohin.description", desc);
            pr.write(area, '0 ' + yposi, obj);
            yposi += XLSH * 3;
            // 1つだけデータがある(1行表示)保存場所をスライドする
            } else {
            area = d_line ? drawPage.trow_body_bdr: drawPage.trow_body;
            if (_hasV(cd)) {
            _setV("shohin.nm", cd);
            } else if (_hasV(nm)) {
            _setV("shohin.nm", nm);
            } else if (_hasV(desc)) {
            _setV("shohin.nm", desc);
            }
            pr.write(area, '0 ' + yposi, obj);
            yposi += XLSH * 2;
            }
            }
            }
            });
            データの取得・加工処理(aggregate:一部抜粋)
              function aggregate() {
            debugger
            aggregate.cond = {};
            // [ データのグループ化はここでします ]
            aggregate.result = {
            ALL: NULL
            }; // { g_key: n, ALL: sum_n }
            // 区分ごとのグループ
            aggregate.groups = {
            ALL: {
            page_num: 0,
            num: 0,
            data: []
            }
            }; // { g_key: { data: [ ], head: { }, page: n } }
            aggregate.page = {}
            drawPage.n = 0;
            // ページ描画のカウンター
            let res;
            return Promise.resolve().then(function() {
            // データ取得
            return getOneData();

            }).then((rslt)=>{
            //念の為extend
            res = fn.extend(TRUE, {}, rslt);
            var rslt = aggregate.result;
            var group_all = aggregate.groups.ALL;
            rslt.ALL = {
            n: res.meisai.length
            // 出力対象消込データ件数
            };
            return setupOneGroupData("all", res, res.meisai);
            }).then(function() {
            return getOneGroupPageCount("all", res);
            });
            } // <-- function aggregate() { ... } <--