夏期休業のお知らせ

                            平成29年8月1日

お客様各位

                        バリアントソフト株式会社

拝啓 盛夏の候、ますますご盛栄のこととお慶び申し上げます。
平素は格別のお引き立てを賜り、厚くお礼申し上げます。
さて、弊社では下記期間を夏期休業日とさせていただいており
ます。
休業期間中は、何かとご迷惑をお掛けすることと存じますが何
卒ご理解とご了承いただきますようお願い申し上げます。

                                    敬具

                  記

【夏期休業期間】

平成29年8月14日(月)~平成29年8月15日(火)

※8月16日(水)からは通常どおり営業いたします。

趣味の話2

電子ドラム届きました。

お風呂に入って、その後子供を寝かしつけてから、部屋にこもり叩いているのですが、
エアコンも扇風機もない為、30分くらいすると汗だくになって、またお風呂に入ると
いうルーチンを毎日しています。その結果、洗濯物が2倍になりました 笑

それと自作の防振台ですが、ネットでは有名な「ディスクふにゃふにゃシステム」と
いうものがあるらしく、それを真似して自分で風呂マット、バランスディスク、ベニヤ板などを
買ってきて作ってみました。

なかなか揺れます。
パッドを叩く度に揺れまくっているので、振動を吸収してくれているとは思うのですが、
やはり下階に振動が伝わっていないか不安でたまりません。
しばらくは弱めに叩きつつ、さらに防音、防震対策をしていきたいと思っています。

高熱

先日、仕事中にものすごい寒気に襲われ、帰宅後に熱を測ってみたところ39度ありました。
翌日朝も熱が下がらず病院に行ったんですが、診断結果はマイコプラズマ気管支炎とのことでした。

ただ全く咳が出ないのとその2日後に喉の奥の方に口内炎らしきものができていて、
前の週に子供がヘルパンギーナに感染していた状況から、おそらくマイコプラズマではなく
ヘルパンギーナにかかっていたんだと思います。

あまり大人には感染しないらしいのですが、私は子供の食べこぼしを食べたことが原因だと思います。

お子さんがいる方はお気をつけください。

趣味の話

私の趣味の話です。

電子ドラム買いました。

まだ届いてないのですが、楽しみすぎて毎日お酒を飲みながらYouTubeで
同じ機種の動画ばかり見ています。

うちはマンションなので、隣の部屋や下階の住人に迷惑をかけないように
防音・防振対策が必要で、防震台の作り方についても勉強中です。

電子ドラムが届いたら写真を撮ってアップしたいと思います。

楽しみです。

海にて

先日、釣りに行った時の話です。

いつもの様に釣りをしていたら20mくらいの離れた所で黒い物体が水上を移動していたので、なにかと思い近づいてみると、それは体長1mくらいのシュモクザメでした。

サメが背びれを水上に出して泳いでいるのを初めて見たのでとても感動しました。

最近、北九州でサメの目撃情報が多発しているらしいので、海のレジャーに行かれる方は気をつけたほうが良いかもしれません。

今度、サメに遭遇したら写真を撮ってアップしたいと思います。

 

コンピュータシステムを守る

巷を賑やかしているランサムウェア「WannaCry」。

防御のためには、一般的に以下の作業を薦められています。

1.Windowsを最新の状態にする。

2.ウイルス対策ソフトのウィルス定義データベースを最新にする。

3.知らない相手のメールは開かないし、添付ファイルは絶対に開かない。

ここまでしたから絶対安全だと確信している方がほとんどではないでしょうか。

しかしながら、絶対はないのです。

日本人の性格は、安全のために何をするかを一生懸命考えます。

でも何かが起きたときのための準備をどうするかを考えるのは苦手なようです。

自分だけは何も起きない。起きてほしくない。起きないでしょう。起きるわけない。

ほとんどの方がそう考えます。

しかしながら、そのときは突然思いがけない方向から訪れるかもしれないのです。

ウイルスの感染からデータを守る時に一番先に考えないといけないことは、

OS・プログラム・データのバックアップを

ネットワークから切断された媒体に保存することなのです。

そしてそれを、できるだけ遠隔地に保存することなのです。

株式会社理経ホームページリニューアル

弊社製品の CampusMagic が掲載されています。

教務システム CampusMagic(キャンパスマジック)
本システムは導入時のコストパフォーマンスに優れるとともに、導入後の運用コストも非常に低く抑えることが可能です。
データは2次利用するために最大限の工夫が施されていますので、せっかく入力したデータが無駄にならないような仕組みも兼ね備えています。

バリアントソフト株式会社

ClosedXMLでExcelファイルに画像を埋め込む

公式版が画像埋め込みをサポートしています。
以下の内容は不要な情報となりました。

Excelファイルの出力でClosedXMLを使うことがありましたが、どうも公式のものは画像埋め込みをサポートしていない模様。

「ClosedXML 画像」で検索すると上位に表示されるページC#でExcelに画像データを埋め込む を参考にさせていただきClosedXMLImageSupportを入手しましたが、本家の最新版と開きがあるようなので、ClosedXMLImageSupportから画像埋め込み関係のコードを本家最新版に取り込みます。

ClosedXMLImageSupportのソリューション内にあるClosedXML_Sandboxが動けば良しとして、ざくっと追加、追記します。

  • ClosedXML\Excel\Drawings\
    • 追加:IXLMarker.cs
    • 追加:IXLPicture.cs
    • 追加:XLMarker.cs
    • 追加:XLPicture.cs
  • ClosedXML\Excel\
    • IXLWorksheet.cs
      • 追加:System.Collections.Generic.List Pictures();
      • 追加:void AddPicture(Drawings.IXLPicture pic);
    • XLWorkbook_Save.cs
      • 追加:using A = DocumentFormat.OpenXml.Drawing;
      • 追加:using Xdr = DocumentFormat.OpenXml.Drawing.Spreadsheet;
      • 追加:private static void AddPictureAnchor(WorksheetPart worksheetPart, Drawings.IXLPicture picture)
      • 内部処理追加:private static void GenerateWorksheetPartContent(WorksheetPart worksheetPart, XLWorksheet xlWorksheet, SaveContext context)
    • XLWorksheet.cs
      • 追加:private List pictures
      • 追加:public List Pictures()
      • 追加:public void AddPicture(Drawings.IXLPicture pic)

これでSandboxを実行するとExcelファイルが出力されて画像も埋め込まれています。
が、しかし。

他サイトの記事にもあるように画像の縦横比を無視してセルにフィットしてしまいます。

ClosedXMLImageSupportから取り込んだXLPictureは、AddMarker()でXLMarkerを追加して、一つ目がfrom、二つ目がtoとしてセルの範囲を指定するようになっています。このtoにあたるMarkerのセル位置とオフセットを上手いこと指定してあげれば画像の縦横比を維持して画像を埋め込むことができるようです。

しかし画像はfromで指定したセルの左上から、toで指定したセルの左上までは拡張されてしまうため、画像が収まる縦横セル数を求めた上でオフセットを指定する必要があります。十分大きな範囲を指定してからどうにかする、という手は使えません。

画像のサイズはピクセルですが、Excelのセル高さ(行高さ)はポイント、セル幅(カラム幅)は標準フォントの数字が何文字表示できるか。なので換算が必要になります。

ポイントからピクセルは簡単ですがカラム幅からピクセルはかなり面倒です。

  1. そのExcelブックの標準フォントとサイズを調べ
  2. TextRenderer.MeasureText()にTextFormatFlags.NoPaddingを指定し、0~9について描画時の最大フォント幅を求め
  3. フォント幅からセルのパディングをもとめ
    (パディング = 切り上げ(フォント幅  / 4) * 2 + 1。*2は両サイドにパディングが入るため。+1はグリッドライン分)
  4. カラムのピクセル幅 = カラム幅 * フォント幅 + パディング

となるようです。
このあたりは
ttps://social.msdn.microsoft.com/Forums/en-US/9a6a9785-66ad-4b6b-bb9f-74429381bd72/margin-padding-in-cell-excel?forum=os_binaryfile

関連ドキュメント : MS-OI29500 の 2.1.595 Part 1 Section 18.3.1.13, col (Column Width & Formatting) f. を参考にしました。

これをカラム毎に計算しながら、fromで指定されたセルから画像が上手く収まるカラム数を求めるのは正直辛いです。

ということでClosedXMLImageSupportから取り込んだXLWorkbook_Save.csのAddPictureAnchor()を弄ることでtoを指定せずに縦横比を維持して画像を埋め込むことができるようにしてみました。

まず、XLPictureのフィールドとしてあって使われていないNoChangeAspect, NoMove, NoResizeをIXLPictureでプロパティとして定義しておきます。XLPicture側ももちろん変更。

その上で、XLWorkbook_Save.csに取り込んだAddPictureAnchor()

private static void AddPictureAnchor(WorksheetPart worksheetPart, Drawings.IXLPicture picture)
{
    /* 省略 */
    var markers = picture.GetMarkers();
    Xdr.TwoCellAnchor twoCellAnchor;
    Xdr.FromMarker fMark;
    Xdr.ToMarker tMark;
    if (markers.Count == 2)
    {
    fMark = new Xdr.FromMarker
    {
        ColumnId = new Xdr.ColumnId(markers[0].ColumnId.ToString()),
        RowId = new Xdr.RowId(markers[0].RowId.ToString()),
        ColumnOffset = new Xdr.ColumnOffset((markers[0].ColumnOffset + picture.PaddingX).ToString()),
        RowOffset = new Xdr.RowOffset((markers[0].RowOffset + picture.PaddingY).ToString())
    };
    tMark = new Xdr.ToMarker
    {
        ColumnId = new Xdr.ColumnId(markers[1].ColumnId.ToString()),
        RowId = new Xdr.RowId(markers[1].RowId.ToString()),
        ColumnOffset = new Xdr.ColumnOffset((markers[1].ColumnOffset + picture.PaddingX).ToString()),
        RowOffset = new Xdr.RowOffset((markers[1].RowOffset + picture.PaddingY).ToString())
    };
    }
    else
    {
    fMark = new Xdr.FromMarker
    {
        ColumnId = new Xdr.ColumnId(markers[0].ColumnId.ToString()),
        RowId = new Xdr.RowId(markers[0].RowId.ToString()),
        ColumnOffset = new Xdr.ColumnOffset((markers[0].ColumnOffset + picture.PaddingX).ToString()),
        RowOffset = new Xdr.RowOffset((markers[0].RowOffset + picture.PaddingY).ToString())
    };
    tMark = new Xdr.ToMarker
    {
        ColumnId = new Xdr.ColumnId(markers[0].ColumnId.ToString()),
        RowId = new Xdr.RowId(markers[0].RowId.ToString()),
        ColumnOffset = new Xdr.ColumnOffset((markers[0].ColumnOffset + extentsCx + picture.PaddingX).ToString()),
        RowOffset = new Xdr.RowOffset((markers[0].RowOffset + extentsCy + picture.PaddingY).ToString())
    };
    }
    twoCellAnchor = new Xdr.TwoCellAnchor(
    fMark, tMark,
        new Xdr.Picture(
            new Xdr.NonVisualPictureProperties(
                new Xdr.NonVisualDrawingProperties { Id = nvpId, Name = picture.Name },
                new Xdr.NonVisualPictureDrawingProperties(new A.PictureLocks { NoChangeAspect = true, NoMove = true, NoResize = true })
            ),
            new Xdr.BlipFill(
                new A.Blip { Embed = drawingsPart.GetIdOfPart(imagePart), CompressionState = A.BlipCompressionValues.Print },
                new A.Stretch(new A.FillRectangle())
            ),
            new Xdr.ShapeProperties(
                new A.Transform2D(
                    new A.Offset { X = 0, Y = 0 },
                    new A.Extents { Cx = extentsCx, Cy = extentsCy }
                ),
                new A.PresetGeometry { Preset = A.ShapeTypeValues.Rectangle }
            )
        ),
        new Xdr.ClientData()
    );

    worksheetDrawing.Append(twoCellAnchor);
}

これを↓こんな感じで。

private static void AddPictureAnchor(WorksheetPart worksheetPart, Drawings.IXLPicture picture)
{
    /* 省略 */
    var xdrPicture = new Xdr.Picture(
                new Xdr.NonVisualPictureProperties(
                    new Xdr.NonVisualDrawingProperties { Id = nvpId, Name = picture.Name },
                    // ここでIXLPictureに追加したプロパティを使用。
                    new Xdr.NonVisualPictureDrawingProperties(new A.PictureLocks { NoChangeAspect = picture.NoChangeAspect, NoMove = picture.NoMove, NoResize = picture.NoResize })
                ),
                new Xdr.BlipFill(
                    new A.Blip { Embed = drawingsPart.GetIdOfPart(imagePart), CompressionState = A.BlipCompressionValues.Print },
                    new A.Stretch(new A.FillRectangle())
                ),
                new Xdr.ShapeProperties(
                    new A.Transform2D(
                        new A.Offset { X = 0, Y = 0 },
                        new A.Extents { Cx = extentsCx, Cy = extentsCy }
                    ),
                    new A.PresetGeometry { Preset = A.ShapeTypeValues.Rectangle }
                )
            );

    var markers = picture.GetMarkers();

    var fMark = new Xdr.FromMarker
    {
        ColumnId = new Xdr.ColumnId(markers[0].ColumnId.ToString()),
        RowId = new Xdr.RowId(markers[0].RowId.ToString()),
        ColumnOffset = new Xdr.ColumnOffset((markers[0].ColumnOffset + picture.PaddingX).ToString()),
        RowOffset = new Xdr.RowOffset((markers[0].RowOffset + picture.PaddingY).ToString())
    };

    if (markers.Count == 2)
    {
        var tMark = new Xdr.ToMarker
        {
            ColumnId = new Xdr.ColumnId(markers[1].ColumnId.ToString()),
            RowId = new Xdr.RowId(markers[1].RowId.ToString()),
            ColumnOffset = new Xdr.ColumnOffset((markers[1].ColumnOffset + picture.PaddingX).ToString()),
            RowOffset = new Xdr.RowOffset((markers[1].RowOffset + picture.PaddingY).ToString())
        };

        var twoCellAnchor = new Xdr.TwoCellAnchor(fMark, tMark, xdrPicture, new Xdr.ClientData());

        worksheetDrawing.Append(twoCellAnchor);
    }
    else
    {
        var ext = new Xdr.Extent { Cx = extentsCx, Cy = extentsCy };
        var oneCellAnchor = new Xdr.OneCellAnchor(fMark, ext, xdrPicture, new Xdr.ClientData());

        worksheetDrawing.Append(oneCellAnchor);
    }
}

元のコードはMarker一つの場合にfromをtoとしても使い、常にTwoCellAnchorを使っていますが、これをOneCellAnchorを使うよう変更しています。あとnew PictureLocks()の箇所ですね。
これでExcelで普通に画像を挿入した場合と同じように埋め込まれるようになりました。

using (FileStream strm = new FileStream(@"sample.png", FileMode.Open))
{
    XLPicture pic = new XLPicture { ImageStream = strm, Name = "test image" };
    pic.AddMarker(new XLMarker { ColumnId = 2, RowId = 3 });
    worksheet.AddPicture(pic);
}

ついでにXLPictureのResize()も少し手を加えると拡大縮小して埋め込めるようになります。

IXLPictureのプロパティにしたNoMoveをtrueにすると埋め込んだ画像が移動できなくなります。NoResizeをtureにするとサイズが変更できなくなります。

XLPictureのPddingX, PddingY(またはEMUOffsetX, EMUOffsetY)にピクセル単位で値を指定するとXLMarkerで指定したセルからのオフセットとして画像が埋め込まれます。XLMarkerのColumnOffset、RowOffsetでもオフセットによる位置指定ができますが、こちらはEMUで指定する必要があるので面倒です。

EEMUOffsetX, EMUOffsetYは設定した値がPaddingX、PaddingYから取得される際にConvertToEmu()を通るので、「設定したピクセル値がEMUに変換されるオフセット」のようです。EMUのつもりで設定するとおかしなことになります。

マルウェア感染

セキュリティ企業Check Point Software Technologiesが、大手2社の販売チェーンから購入したAndroidスマートフォンの36台が、販売時点で既にマルウェアに感染済みだったことを明らかにしたそうです。

日本では目にする機会が少ないメーカーが多いそうですが、なかにはSamsungのGalaxy NoteシリーズやGalaxy Sシリーズ、AsusのZenFone2 など日本国内でも人気モデルが含まれているようです。

どんなに使用者が注意を払っていても購入する時点で感染済みだったらどうしようもないですね。セキュリティ対策ソフト等を使用して出来る限りの安全は確認したいです。