2018年12月28日金曜日

iCalendar 仕様

iCalendar 仕様

iCalendar コンテンツの作成にとりあえず役立ちそうな情報の抜書き。(正確な仕様は RFC にあたること)

目次

仕様書

iCalendar は RFC で定義されている。
  • RFC2445 (November 1998) Internet Calendaring and Scheduling Core Object Specification (iCalendar)
  • RFC2446 (November 1998) iCalendar Transport-Independent Interoperability Protocol (iTIP) Scheduling Events, BusyTime, To-dos and Journal Entries
  • RFC2447 (November 1998) iCalendar Message-Based Interoperability Protocol (iMIP)

全般

  • MIME タイプは text/calendar。テキストファイルとして記述。(RFC2445 3.1)
  • ファイル拡張子は ics、Macintosh ファイルタイプコードは iCal。free or busy time information のみ ifb。Macintosh では iFBf。(RFC2445 3.10)
  • 各行の区切りは CR+LF。(RFC2445 4.1)
  • 1行 75 octet 以内。行頭に空白を入れない。2行以上続ける場合に、2行目以降の行頭に空白を入れる。(RFC2445 4.1)
  • デフォルトの文字セットは UTF-8。(RFC2445 4.1.4)
  • 日付と時刻を一緒に記述する時は、間を T で区切る。例: 19980119T230000 (RFC2445 4.3.5)
    これらの日付時刻書式は、ISO 8601 Data Elements and Interchange Formate -- Information Interchange -- Representation of Dates and Times に定められた形式。
  • 時刻は、末尾に Z がつけば UTC、つかなければローカル時間。(RFC2445 4.3.12)

構造

   
BEGIN:VCALENDAR
PRODID:
VERSION:2.0
METHOD:PUBLISH
   
   
BEGIN:VTIMEZONE
TZID:...
   
   
BEGIN:STANDARD
 :
END:STANDARD
   
   
BEGIN:DAYLIGHT
 :
END:DAYLIGHT
   
   
END:VTIMEZONE
   
   
BEGIN:VEVENT
ORGANIZER:MAILTO:CI5M-NMR@asahi-net.or.jp
DTSTART;VALUE=DATE:20001009
DTEND;VALUE=DATE:20001010
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=MO;BYMONTH=10;BYSETPOS=2;WKST=SU
LOCATION:
TRANSP:TRANSPARENT
SEQUENCE:
UID:
DTSTAMP:
CATEGORIES:
DESCRIPTION:
 :
SUMMARY:
PRIORITY:
CLASS:PUBLIC
END:VEVENT
   
   
END:VCALENDAR
   

詳細

BEGIN, END

(RFC2445 4.4, 4.6) VCALENDAR, VTIMEZONE などすべてのコンポーネントは、必ず
BEGIN:コンポーネント名
ではじまり
END:コンポーネント名
で終わらなければならない。

VCALENDAR

(RFC2445 4.7)
CALSCALE
(RFC2445 4.7.1) ?????????????????? 今のところ、定義済みはデフォルトの GREGORIAN だけ。
PRODID
(RFC2445 4.7.3) 必須。iCalendar オブジェクトを生成したアプリケーションの識別情報。
VERSION
(RFC2445 4.7.4) 必須。RFC2445 は 2.0。
METHOD
(RFC2445 4.7.2) ???? 値には PUBLISH, REQUEST がある? MIME メッセージで使用する場合、Content-type "method" の値と一致しなければならない。
(RFC2446) ??????????????????????

VTIMEZONE

(RFC2445 4.6.5) タイムゾーンの情報を定義する。TZID と、最低1つの STANDARD または DAYLIGHT の定義を含んでいなければならない。
日本の場合は次の記述でよい?
BEGIN:VTIMEZONE
TZID:Japan
BEGIN:STANDARD
DTSTART:19390101T000000
TZOFFSETFROM:+0900
TZOFFSETTO:+0900
TZNAME:JST
END:STANDARD
END:VTIMEZONE
TZID
必須。タイムゾーンを識別するための文字列。
STANDARD
(RFC2445 4.6.5) 標準時刻の情報。DTSTART, TZOFFSETFROM, TZOFFSETTO を含まなければならない。 ただし Microsoft Outlook 2000 (以下 Outlook) では DTSTART を省略している?
DTSTART
タイムゾーンの使用がはじまった日時???
TZOFFSETFROM
(RFC2445 4.8.3.3) VTIMEZONE に必須。現在のタイムゾーンがはじまる前に使われていたタイムゾーンの UTC からのオフセット???(夏時間がある地域の場合は、夏時間のオフセット???)
TZOFFSETTO
VTIMEZONE に必須。現在のタイムゾーンの UTCからのオフセット???
DAYLIGHT
夏時間の情報。DTSTART, TZOFFSETFROM, TZOFFSETTO については STANDARD に同じ。

VALARM

(RFC2445 4.6.6) 未調査。

VEVENT

ORGANIZER
(RFC2445 4.8.4.3) カレンダー・コンポーネントのOrganizer(主催者)情報。グループのスケジュール・カレンダーをもつコンポーネントには必須。
ORGANIZER;CN=NOMURA Mahito:MAILTO:CI5M-NMR@asahi-net.or.jp
CONTACT
(RFC2445 4.8.4.2) カレンダー・コンポーネントに関連した情報のコンタクト先。
DTSTART
(RFC2445 4.8.2.4) 開始日時。定期的なイベントの場合は、最初の分の開始日時。
タイムゾーンを明示する場合は、
DTSTART;TZID=Japan:19970714T133000
のようにあらかじめ VTIMEZONE で宣言した TZID を指定する。
DTEND
(RFC2445 4.8.2.2) 終了日時。定期的なイベントの場合は、最初の分の終了日時。(祝日のように終日の場合は、翌日の 00:00:00 を指定すればよい?)
RRULE
(RFC2445 4.8.5.4) 定期的なイベントについて、頻度、月日、間隔などの規則。
RRULE;FREQ=DAILY;COUNT=10
(DTSTART の日から同一時刻で毎日、全10回) 以下の指定可能な属性は (RFC2445 4.3.10) を参照。
BYMONTH
実際の月の指定。
BYMONTHDAY
BYMONTH と組み合わせて、実際の日の指定。マイナスの場合は、DTSTART から値の分だけ先行する期間。
BYDAY
LOCATION
(RFC2445 4.8.1.7) 場所の指定。
TRANSP
(RFC2445 4.8.2.7) 設定した時間の状態。OPAQUE (デフォルト), TRANSPARENT が指定可能。 Outlook では「予定の公開方法」に反映される。これがなかったり TRANSP:OPAQUE だと「予定あり」、TRANSP:TRANSPARENT が指定されていると「空き時間」
SEQUENCE
(RFC2445 4.8.7.4) リビジョンのシーケンス番号。カレンダーコンポーネントがはじめて作成された時に0、Organizerによる修正更新があるたびに増分。
UID
(RFC2445 4.8.4.7) Unique Identifier、全世界でユニークな永続的ID。RFC 822 の addr-spec に従ったシンタックスを推奨。
メールやネットニュースのMessage-IDみたいなものか。
DTSTAMP
(RFC2445 4.8.7.2) オブジェクトの作成日時。 Outlook では必須。
CATEGORIES
(RFC2445 4.8.1.2) コンポーネントを分類するためのカテゴリー。 Outlook の「分類」に対応。
SUMMARY
(RFC2445 4.8.1.12) カレンダー・コンポーネントの短いサマリまたはサブジェクト。
件名、見出しに相当。
DESCRIPTION
(RFC2445 4.8.1.5) SUMMARY に対して、カレンダー・コンポーネントの完全な説明。
本文に相当。
PRIORITY
(RFC2445 4.8.1.9) 相対的な優先度を示す整数。最低は0(優先度なし)。
CLASS
(RFC2445 4.8.1.3) アクセス許可の区分。PUBLIC(デフォルト), PRIVATE, CONFIDENTIAL が定義済み
RELATED-TO
(RFC2445 4.8.4.5) 他のカレンダー・コンポーネントとの関連を示す。通常、該当するコンポーネントのUIDを指定。
RELTYPE
(RFC2445 4.2.15) RELATED-TO で示される他コンポーネントとの関係を明示する。PARENT(デフォルト), CHILD, SIBLING

テンプレート

テンプレート。
BEGIN:VCALENDAR
PRODID:-//NOMURA Mahito//Manually//EN
METHOD:PUBLISH
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Japan
BEGIN:STANDARD
DTSTART:19390101T000000
TZOFFSETFROM:+0900
TZOFFSETTO:+0900
TZNAME:JST
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
UID:
DTSTAMP:
SUMMARY:
LOCATION:
DESCRIPTION:
DTSTART;TZID=Japan:
DTEND;TZID=Japan:
RRULE:FREQ=;INTERVAL=;BYMONTH=;BYMONTHDAY=
CATEGORIES:
TRANSP:TRANSPARENT
PRIORITY:0
CLASS:PUBLIC
END:VEVENT
END:VCALENDAR

実装

Outlook 2000 用の .ICS を作る過程で気づいたことのメモ。
  • 1ファイルには1つの VCALENDAR しか記述できない? 2つ以上記述しても、Outlook では最初のものしか認識しない。
  • Outlook 2000 では、1年以上の周期をもつイベント RRULE:FREQ=YEARLY;INTERVAL=2 以上 を認識できない。ただし、月数で1年(12ヶ月)以上の周期は指定できる。
元ネタ http://www.asahi-net.or.jp/~CI5M-NMR/iCal/ref.html

ASP.NET MVCでiCalendarのサービスを追加

ASP.NET MVCのグループウェアを作成後
スマホでカレンダーを見たいと要望される。

ASP.NET MVCでiCalendarのサービスを追加
Nugetから iCal.Netを追加して対応しました。


2018年12月25日火曜日

ASP.NET MVCのKANBAN Library


ASP.NET MVCのKANBAN Libraryを探していたからNugetにあった。

元はgithubに
https://github.com/DlhSoftTeam/Angular-Kanban

個人で管理するならこれくらいで十分
todo見たいに管理出来るから簡単なイメージが良いです。

2018年12月14日金曜日

Telerik ASP.NET MVC Schedulerの日付設定

Kendo().Schedulerで当日日付の指定

@(Html.Kendo().Scheduler<AskaGroup.Models.EventViewModel>()
    .Name("scheduler")
    .Date(new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day))
    .StartTime(new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 9, 00, 00))

    .Height(600)
    .Views(views => {
        views.DayView();
        views.WeekView(weekView => weekView.Selected(true));
        views.MonthView();
        views.AgendaView();
    })
    .Timezone("Etc/UTC")
    .DataSource(d => d
        .Model(m => {
            m.Id(f => f.EventID);
            m.Field(f => f.OwnerID).DefaultValue('1');
            //Set the recurrence ID field from the model:
            m.RecurrenceId(f => f.RecurrenceID);
        })
        .Read("Event_Read", "SDL")
        .Create("Event_Create", "SDL")
        .Destroy("Event_Destroy", "SDL")
        .Update("Event_Update", "SDL")
    )
)

2018年11月27日火曜日

2018年11月6日火曜日

DataPump(expdp,impdp)処理をCtrl+C押しでキャンセルさせてしまった時の対処方法

DataPump(expdp,impdp)処理をCtrl+C押しでキャンセルさせてしまった時の対処方法

OracleでexpdpやimpdpといったData Pumpを実行中に、expコマンドのようにCtrl+Cで処理をキャンセルしてはいけません。 そこがややこしいところ。
もしCtrl+Cでキャンセルしても、処理はバックグラウンドで動き続けます
というわけで、Data Pumpを実行中に誤ってCtrl+Cでキャンセルしてしまった時の対処方法をご紹介です。

JOB名から停止する

処理のJOB名を確認します。
1$ sqlplus sys as sysdba
2select * from DBA_DATAPUMP_JOBS;
3----
4job_expdp1
5----
動作中のJOB名が job_expdp1 ということが分かりました。
あとはこのJOBを指定してコマンドモードに接続して kill_job を発行すれば完了です。
1$ expdp hoge/hogepass attach = job_expdp1
2Export> kill_job
3このジョブを停止しますか([yes]/no)yes
これでバックグラウンドで動作していたData Pump処理が強制終了されます。

元ネタ http://www.lesstep.jp/step_on_board/oracle/77/

2018年11月2日金曜日

Oracle ExpDpのパラメータ and ImpDpのパラメータ

batch file
expdp user/pass@ORCL parfile=exp_m.txt

exp_m.txt
DIRECTORY=ORA_EXP
DUMPFILE=exp_m
LOGFILE=exp_m.log
reuse_dumpfiles=YES
TABLES=(hogehome)



batch file
impdp user/pass@ORCL parfile=imp_m.txt


imp_m.txt
directory=ORA_EXP
dumpfile=exp_m.dmp
logfile=impdp_m.log
TABLE_EXISTS_ACTION=REPLACE
TABLES=(hogehoge)

2018年10月31日水曜日

EPPLUS 折り返して全体を表示 セルに合わせて縮小

折り返して全体を表示
sheet.Cells["A1"].Value = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
sheet.Cells["A1"].Style.WrapText = true;

セルに合わせて縮小
sheet.Cells["A3"].Value = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
sheet.Cells["A3"].Style.ShrinkToFit = true;

2018年10月30日火曜日

FireFox しばらく未接続語、タブもしくはurlを変更しても新規ページが表示されない

FireFox しばらく未接続語、タブもしくはurlを変更しても新規ページが表示されない

  1. アドレスバーabout:config と入力し、Enter キーを押します。
    • about:config の "動作保証対象外になります!" という警告ページが表示されます。危険性を承知の上で使用する をクリックし、about:config ページを開いてください。
  2. 設定リスト内で右クリック して 新規作成 を選択し、真偽値 を選択してください。
  3. 新しい 真偽値の設定名 フィールドに network.dns.disablePrefetch と入力し、OK ボタンをクリックしてください。
  4. 次に、true を選択して値を設定し、OK ボタンをクリックしてください。 

2018年10月25日木曜日

EPPLUS 数字フォーマット マイナスなら赤字で編集を行う

EPPLUS 数字フォーマット マイナスなら赤字で編集を行う

sheet.Column(10).Style.Numberformat.Format = "#,##0; [red]-#,##0";

 通常は #,##0        色指定無し
[red]-#,##0           マイナスなら赤で編集 数字3桁でカンマ編集

2018年10月24日水曜日

C# font 複数の書式を設定する場合

C# font 複数の書式を設定する場合

// 上の例に加え、斜体のスタイルを設定する
 this.textBox1.Font = new Font("Arial", 12, FontStyle.Bold | FontStyle.Italic);

FontStyle を | で結合する

2018年10月23日火曜日

Oracle Sqlplusで余計な出力をしない方法

set echo off
set linesize 1000
set pagesize 0
set trimspool on
set feedback off
set colsep ','
spool c:\temp\tab.csv
select * from tab;
spool off

EPPlusのグルーピング方法

EPPlusのグルーピング方法

//明細グルーピング編集
sheet.Row(vY).OutlineLevel = 2;
sheet.Row(vY).Collapsed = true;

//合計グルーピング編集
sheet.Row(vY).OutlineLevel = 1;

Level = 1を総合計
Level = 2を担当者合計に割当

C# key break処理 キーブレイク処理

C#でキーブレイク処理をすることになった。
COBOLの時は1件読込み後、キーブレイク変数をセットとして
perform untilで回していたけど、C#の場合は、LINQを使った方がきれいに書ける。

            //最初は月度でブレイク
            var yearMonths = items.GroupBy(x => x.月度);

            foreach (var ym in yearMonths) {

                //シート追加&ヘッダ処理
                if (ym.Key == pic売上年月_開始.SelectedDate.Value.ToString("yyyyMM")) {   //最初の月度ならシート名を編集
                    sheet.Name = ym.Key.Substring(0, 4) + "年" + ym.Key.Substring(4, 2) + "月";
                }
                else {
                    package.Workbook.Worksheets.Add(ym.Key.Substring(0, 4) + "年" + ym.Key.Substring(4, 2) + "月");
                    vSt++;
                    sheet = package.Workbook.Worksheets[vSt];
                }

                sheet.Cells["F1"].Value = ym.Key.Substring(0,4) + " 年 " + ym.Key.Substring(4,2) + " + 月現在";
                sheet.Cells["P1"].Value = DateTime.Now.ToString("    yyyy/MM/dd HH:mm:ss");

                //列Aから列Eまで非表示
                sheet.Column(1).Hidden = true;
                sheet.Column(2).Hidden = true;
                sheet.Column(3).Hidden = true;
                sheet.Column(4).Hidden = true;
                sheet.Column(5).Hidden = true;

                sheet.Column(7).Hidden = true;
                sheet.Column(8).Hidden = true;
                sheet.Column(9).Hidden = true;

                //ヘッダー項目編集
                sheet.Cells["F1"].Value = DateTime.Today.ToString("yyyy 年 MM月現在");
                sheet.Cells["K1"].Value = "  *** 担当者別売上統計表 ***";
                sheet.Cells["P1"].Value = DateTime.Now.ToString("    yyyy/MM/dd HH:mm:ss");

                sheet.Cells["A3"].Value = "年月";
                sheet.Cells["B3"].Value = "部門";
                sheet.Cells["C3"].Value = "部門名";
                sheet.Cells["D3"].Value = "課";
                sheet.Cells["E3"].Value = "課名";
                sheet.Cells["F3"].Value = " コード担当者名";
                sheet.Cells["G3"].Value = "担当者名";
                sheet.Cells["H3"].Value = "得意先";
                sheet.Cells["I3"].Value = "得意先名";
                sheet.Cells["J3"].Value = "純売上";
                sheet.Cells["K3"].Value = "粗利";
                sheet.Cells["L3"].Value = "粗利率";
                sheet.Cells["M3"].Value = "売上";
                sheet.Cells["N3"].Value = "返品";
                sheet.Cells["O3"].Value = "返品率";
                sheet.Cells["P3"].Value = "値引";
                sheet.Cells["Q3"].Value = "値引率";
                sheet.Cells["R3"].Value = "売上目標";
                sheet.Cells["S3"].Value = "達成率";

                sheet.Cells["K1"].Style.Font.SetFromFont(new Font("MS Mincho", 16, FontStyle.Bold));

                sheet.Cells["A3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["B3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["C3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["D3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["E3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["F3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["G3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["H3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["I3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["J3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["K3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["L3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["M3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["N3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["O3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["P3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["Q3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["R3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                sheet.Cells["S3"].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));

                sheet.Column(06).Width = 30;    //F
                sheet.Column(11).Width = 16;    //J
                sheet.Column(12).Width = 16;    //K
                sheet.Column(13).Width = 7.5;   //L
                sheet.Column(14).Width = 16;    //M
                sheet.Column(15).Width = 16;    //N
                sheet.Column(16).Width = 7.5;   //O
                sheet.Column(17).Width = 16;    //P
                sheet.Column(18).Width = 7.5;   //Q
                sheet.Column(19).Width = 7.5;   //R

                //合計初期化
                tl1純売上 = 0;
                tl1粗利 = 0;
                tl1売上 = 0;
                tl1返品 = 0;
                tl1値引 = 0;
                tl1売上目標 = 0;

                //自社他社区分のヘッダ編集
                vY = 4;

                //自社他社区分でブレイク
                var v自社他社s = ym.GroupBy(x => x.自社他社区分);

                foreach (var v自社他社 in v自社他社s) {

                    //ヘッダ編集
                    if (v自社他社.Key == "2") {
                        sheet.Cells[vY, 06].Value = "【区分 一般売上】";
                    }
                    else {
                        sheet.Cells[vY, 06].Value = "【区分 社内売上】";
                    }
                    sheet.Cells[vY, 06].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                    vY++;

                    //初期化
                    tl2純売上 = 0;
                    tl2粗利 = 0;
                    tl2売上 = 0;
                    tl2返品 = 0;
                    tl2値引 = 0;
                    tl2売上目標 = 0;

                    //部門でブレイク
                    var v部門s = v自社他社.GroupBy(x => x.部門コード);

                    foreach (var v部門 in v部門s) {

                        var s1 = items.Where(x => x.月度 == ym.Key
                                               && x.自社他社区分 == v自社他社.Key
                                               && x.部門コード == v部門.Key).FirstOrDefault();

                        //ヘッダ編集
                        sheet.Cells[vY, 06].Value = s1.部門コード + " " + s1.部門名;
                        sheet.Cells[vY, 06].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));
                        vY++;

                        //初期化
                        tl3純売上 = 0;
                        tl3粗利 = 0;
                        tl3売上 = 0;
                        tl3返品 = 0;
                        tl3値引 = 0;
                        tl3売上目標 = 0;

                        //課でブレイク
                        var v課s = v部門.GroupBy(x => x.課コード);

                        foreach (var v課 in v課s) {

                            var s2 = items.Where(x => x.月度 == ym.Key
                                                   && x.自社他社区分 == v自社他社.Key
                                                   && x.部門コード == v部門.Key
                                                   && x.課コード == v課.Key).FirstOrDefault();

                            //初期化
                            tl4純売上 = 0;
                            tl4粗利   = 0;
                            tl4売上   = 0;
                            tl4返品   = 0;
                            tl4値引   = 0;
                            tl4売上目標 = 0;

                            //担当者でブレイク
                            var v担当者s = v課.GroupBy(x => x.担当者コード);

                            foreach (var v担当者 in v担当者s) {

                                var s3 = items.Where(x => x.月度 == ym.Key
                                                       && x.自社他社区分 == v自社他社.Key
                                                       && x.部門コード == v部門.Key
                                                       && x.課コード == v課.Key).FirstOrDefault();

                                //初期化
                                tl5純売上 = 0;
                                tl5粗利 = 0;
                                tl5売上 = 0;
                                tl5返品 = 0;
                                tl5値引 = 0;

                                //明細出力
                                var recs = items.Where(x => x.月度 == ym.Key
                                                        && x.自社他社区分 == v自社他社.Key
                                                        && x.部門コード == v部門.Key
                                                        && x.課コード == v課.Key
                                                        && x.担当者コード == v担当者.Key);

                                foreach (var rec in recs) {
                                    //明細編集
                                    v純売上 = (rec.売上金額計 + rec.返品金額計);
                                    v粗利率 = func率計算(rec.粗利金額計, v純売上);
                                    v返品率 = func率計算(rec.返品金額計, rec.売上金額計);
                                    v値引率 = func率計算(rec.値引金額計, v純売上);

                                    sheet.Cells[vY, 01].Value = rec.月度;
                                    sheet.Cells[vY, 02].Value = rec.部門コード;
                                    sheet.Cells[vY, 03].Value = rec.部門名;
                                    sheet.Cells[vY, 04].Value = rec.課コード;
                                    sheet.Cells[vY, 05].Value = rec.課名;
                                    sheet.Cells[vY, 06].Value = "    " + rec.得意先コード + " " + rec.得意先名;
                                    sheet.Cells[vY, 07].Value = rec.担当者名;
                                    sheet.Cells[vY, 08].Value = rec.得意先コード;
                                    sheet.Cells[vY, 09].Value = rec.得意先名;

                                    sheet.Cells[vY, 10].Value = v純売上;
                                    sheet.Cells[vY, 11].Value = rec.粗利金額計;
                                    sheet.Cells[vY, 12].Value = v粗利率;
                                    sheet.Cells[vY, 13].Value = rec.売上金額計;
                                    sheet.Cells[vY, 14].Value = rec.返品金額計;
                                    sheet.Cells[vY, 15].Value = v返品率;
                                    sheet.Cells[vY, 16].Value = rec.値引金額計;
                                    sheet.Cells[vY, 17].Value = v値引率;
                                    sheet.Cells[vY, 18].Value = "";
                                    sheet.Cells[vY, 19].Value = "";

                                    //集計計算
                                    tl5純売上 += v純売上;
                                    tl5粗利 += rec.粗利金額計;
                                    tl5売上 += rec.売上金額計;
                                    tl5返品 += rec.返品金額計;
                                    tl5値引 += rec.値引金額計;

                                    //セーブ項目
                                    sv売上目標 = rec.目標金額計;
                                    sv担当者Cd = rec.担当者コード;
                                    sv担当者名 = rec.担当者名;

                                    vY++;
                                }

                                //集計計算
                                tl4純売上 += tl5純売上;
                                tl4粗利 += tl5粗利;
                                tl4売上 += tl5売上;
                                tl4返品 += tl5返品;
                                tl4値引 += tl5値引;
                                tl4売上目標 += sv売上目標;

                                //担当者合計出力
                                set合計Row(ref sheet, vY, "     * " + sv担当者Cd + " " + sv担当者名,
                                        tl5純売上,
                                        tl5粗利,
                                        tl5売上,
                                        tl5返品,
                                        tl5値引,
                                        sv売上目標);
                                vY++;
                            }

                            //集計計算
                            tl3純売上 += tl4純売上;
                            tl3粗利   += tl4粗利;
                            tl3売上   += tl4売上;
                            tl3返品   += tl4返品;
                            tl3値引   += tl4値引;
                            tl3売上目標 += tl4売上目標;

                            //課合計出力
                            set合計Row(ref sheet, vY, "     * " + s2.課コード + " " + s2.課名,
                                    tl4純売上,
                                    tl4粗利,
                                    tl4売上,
                                    tl4返品,
                                    tl4値引,
                                    tl4売上目標);
                            vY++;
                        }

                        //集計計算
                        tl2純売上 += tl3純売上;
                        tl2粗利   += tl3粗利;
                        tl2売上   += tl3売上;
                        tl2返品   += tl3返品;
                        tl2値引   += tl3値引;
                        tl2売上目標 += tl3売上目標;

                        //部門合計出力
                        set合計Row(ref sheet, vY, "    ** " + s1.部門コード + " " + s1.部門名,
                                tl3純売上,
                                tl3粗利,
                                tl3売上,
                                tl3返品,
                                tl3値引,
                                tl3売上目標);
                        vY++;
                    }

                    //集計計算
                    tl1純売上 += tl2純売上;
                    tl1粗利   += tl2粗利;
                    tl1売上   += tl2売上;
                    tl1返品   += tl2返品;
                    tl1値引   += tl2値引;
                    tl1売上目標 += tl2売上目標;

                    //自社他社区分合計出力
                    set合計Row(ref sheet, vY, "   *** 区分計",
                            tl2純売上,
                            tl2粗利,
                            tl2売上,
                            tl2返品,
                            tl2値引,
                            tl2売上目標);
                    vY++;
                }

                //月度合計出力
                set合計Row(ref sheet, vY, "  **** 総合計",
                        tl1純売上,
                        tl1粗利,
                        tl1売上,
                        tl1返品,
                        tl1値引,
                        tl1売上目標);
            }

            package.Save();
        }
    }

    private void set合計Row(ref ExcelWorksheet isheet,
                            int iY,
                            string i計名,
                            decimal i純売上,
                            decimal i粗利,
                            decimal i売上,
                            decimal i返品,
                            decimal i値引,
                            decimal i売上目標) {

        isheet.Cells[iY, 06].Value = i計名;
        isheet.Cells[iY, 06].Style.Font.SetFromFont(new Font("MS Mincho", 11, FontStyle.Bold));

        isheet.Cells[iY, 10].Value = i純売上;
        isheet.Cells[iY, 11].Value = i粗利;
        isheet.Cells[iY, 12].Value = func率計算(i粗利, i純売上);
        isheet.Cells[iY, 13].Value = i売上;
        isheet.Cells[iY, 14].Value = i返品;
        isheet.Cells[iY, 15].Value = func率計算(i返品, i売上);
        isheet.Cells[iY, 16].Value = i値引;
        isheet.Cells[iY, 17].Value = func率計算(i値引, i純売上);
        isheet.Cells[iY, 18].Value = i売上目標;
        isheet.Cells[iY, 19].Value = func率計算(i純売上, i売上目標);
    }
    private decimal func率計算(decimal i1, decimal i2) {
        decimal vCal = 0;
        try {
            vCal = (i1 / i2) * 100;
        }
        catch { vCal = 0; }

        return vCal;
    }