Delphi

Office Mobile でOLEが使えるか検証

Lenovo Yoga tablet 2 8inc に Windows10にアップグレードしましたが、
本来の目的は、Office mobileが、OLE?で
使えるかとう、検証のため。

Excel mobile

Office mobileは、10.1inc以下のタブレットであれば、無償で使えるOfficeで、

>?「Office Mobile」のライセンス @日経トレンド

メインアプリから制禦し、
印刷だけを、Excelさせようと目論んだのですが、

 

結果は、

Office Mobile Excel OLE

 

ダメみたい・・・Orz

 

残念です・・・

***

Excel Viewer を試してみましたが、

> https://www.microsoft.com/en-us/download/details.aspx?id=10

同じく、ダメ。

 

と、当然か・・・

試しに、OpenOfficeが、外部制御(OLE)に対応しているか調べてみたところ、
どうやら、出来るみたい。

>?VBからOpenOffice.orgを操作する

さらに、

OpenOfficeの利用 @Delphi
OpenOfficeの利用 @Delphi
OpenOfficeの制御サンプル @Delphi
OpenOfficeの制御サンプル @Delphi

http://edn.embarcadero.com/jp/article/40857/images/40857/b5.pdf より

Microsoft Excel を、買ってもらったほうが、
工程的には、楽なんだけど、

できるだけ、費用負担を軽くしたいので、ちょっと、試してみます。

OpenOffice CALc 印刷サンプル @Delphi

ありがたいことに、サンプルまで♪

PS.

Officeのライセンスを調べれば調べるほど、隙間がないことがわかります。
そして、一見わかりにくくしてあるので、ややこしいと思われていますが、
実際のところ、とってもややこしいです!

 

一番ややこしくさせている原因が、

Office365というサービス。

ざっくり言うと、オンラインストレージや、
最新のプログラムにアップグレード出来るサービスですが、

では、このサービス期間が切れた場合、どうなるかというと、

Officeはそのまま使えます!

次に、ややこしくしている

アップグレードと、アップデート

Office2013を使っていて、Office365のサービスに加入していると、
Office2016にアップグレードすることが出来ます。

その後、Office365のサービスが切れたとして、
Office2016のアップデートはされます(バグフィックスとか)が、
Office 2017へのアップグレードは出来ません。

Office365 Solo以外の製品は、「永年使用可」と書いてあり、
Office365 が切れていても、そのバージョンのOfficeは使い続けられますが、
サポート期限が儲けられているため、
それ以降は、バグフィックスなどは行われなくなります。

***

1ライセンス/2PC

Office 2016 Personalが、約30000円

1つ買うと、2つのPCに入れていいけど、
使える人は、一人だけ。

例 > ひとり暮らしで、お家にディスクトップPCとノートPCがある場合、
これら2台にインストールするのは、OK

例 > 家族3人暮らしで、お家にディスクトップPCとノートPCがある場合、
これら2台にインストールしてもいいけど、使っていいのはお父さんだけ。

半額で1ライセンス/1PCで売ってくれたら、
話は早いんだけど、
昔から、Officeはこの値段で、
最近、2台持つ人も多くなったので、

もう1台にインストールしてもいいよ

というやつ。

でも、誰が使っているか、なんてコンピュータにはわかりません。
顔認証機能を付けないかぎり、ネ。


 

ま、こんなルールになっているわけですから、
これを、お客様に2台入れてもいいよ、とは言いにくいため、
OpenOfficeがOLEで使えるのなら、
そっちのほうが制約がなくていいわけです。

どうせ、年に数回レイアウト変更と、
印刷にしか、使わないのですから!

-

TDBCtrlGridの背景色を個別に変える@Delphi

ちょっと、思いつきで頼まれた仕事のサンプルを作成中。
見積もり以前の段階なのに、ここまで作りこんでしまうのも、どうかと思うが。

今回、TDBCtrlGridに個別の配色をしたく、試行錯誤した。

***

まず、OnPanelPaintのイベント。

>> http://delphiexamples.com/databases/colorctgrid.html

にあるように、

if Odd(index) then? begin
  DBCtrlGrd1.Color:=clSkyBlue;
end else begin
   DBCtrlGrd1.Color:=clCream;

end;

※奇数、偶数で、配色を変えるコード

やりたいことは、レコードに保存した色で、パネル毎の背景色を変えたいので、
ちょっと、これでは物足りず。

Canvasに直接描画するも、そのパネルがどのデータを持っているか、取り出せないので、
アクティブ・レコードの時にしか、色データを取り出せず・・・

 

数時間、WEBを探し回るが、そんなサンプルに出会えず、
やっと見つけた、これ↓

>>?https://github.com/Evil-Spirit/Nutmeg/blob/master/Library/AlphaControls/AlphaDB/acDBCtrlGrid.pas

DB系コンポーネントは、どれもそうだけど、
DataLinkというプロパティーで、データを取得している。
特に、TDBGridや、TDBCtrlGridは、アクティブ・レコード以外のデータを
参照する必要があるため、内部的にDataLinkを参照しているのだけど、

これが、

private 宣言なので、外部のユニットからは、参照出来ないわけで。

上記は、コンポーネントなんだけど、
DataLink プロパティーの値を引いてくることが出来る、簡単なコードがあった!!

Result := TDBCtrlGrid_(Self).FDataLink;

TDBCtrlGrid_ というのは、TDBCtrlGridから派生させたもので、

  TDBCtrlGrid_ = class(TWinControl)
  private
    FDataLink: TDBCtrlGridLink;
  end;

たった、これだけのもの。

 

privateは、同一ファイル上でしか、アクセスできないけど、
プロジェクト内のフォーム(TForm1)上で、TDBCtrlGrid_を
派生させて、キャストすれば、同一ファイル上になるので、
アクセスが出来るようになるという、方法。

 

DataLinkをpublic宣言に置き換えた、コンポーネントを作れば可能なんだけど、
それを、キャストでやってしまうというのは、

 

目からウロコでした!!

 

このやり方で、

procedure DBCtrlGridPaintPanel(DBCtrlGrid: TDBCtrlGrid; Index: Integer);
var
  DL: TDataLink;
  SaveActive: Integer;
begin
  // paint color //
  with DBCtrlGrid do
    if Index <> PanelIndex then
    begin
      DL := TDBCtrlGrid_(DBCtrlGrid).FDataLink;

      if not VarIsNull(DL.DataSet.FieldValues['color']) then begin
        Color := DL.DataSet.FieldValues['color'];

      end else
        Color := DBCtrlGrid_Color;

    end;

※DataLink上のデータは、ActiveRecord = Index(イベントの変数)で、取得できる

課題として、

大量の描画イベントが発生してしまうため、その対応を検討中。


していましたが、

完成しました!!

 

TDBCtrlGridの背景色を個別に変える@Delphi
左下の薄い青が、選択した項目で、 右上はデータと連動して、背景色を変わってます。

 

試行錯誤の過程は、あえてコメントアウトして、残していますが、
コメント行は、全消しでOK。

procedure TfMain.DBCtrlGridPaintPanel(DBCtrlGrid: TDBCtrlGrid; Index: Integer);
var
  DL: TDataLink;
  SaveActive: Integer;
begin
  // paint color //
  with DBCtrlGrid do
    if Index <> PanelIndex then begin
      DL := TDBCtrlGrid_(DBCtrlGrid).FDataLink;

//      SaveActive := DL.ActiveRecord;
//      DL.ActiveRecord := Index;
      try
//        DebugPrint(DL.DataSet.FieldValues['color']);

        if not VarIsNull(DL.DataSet.FieldValues['color']) then begin
          // http://delphimaster.net/view/3-51640
//          Canvas.Brush.Color := DL.DataSet.FieldValues['color'];
//          Canvas.FillRect(Rect(0, 0, PanelHeight, PanelWidth));

          Panel1.Color := DL.DataSet.FieldValues['color'];

        end else
          Panel1.Color := DBCtrlGrid_Color;

      finally
//        DL.ActiveRecord := SaveActive;

      end;
    end else
      Panel1.Color := DBCtrlGrid.SelectedColor;

 end;

Panel1というのは、TDBCtrlGrid上に置いた、
何の変哲もないTPanelですが、ちゃんと理由ははあります。

TDBCtrlGrid上には、TDBEditを幾つか置いていますが、
編集モードでない時は、カーソル表示させたくないので、
Enabled := false としたところ、文字が灰色になってしまうため、
(ReadOnlyだと、カーソルは表示されてしまう)

Panelを置き、それをEnabled := falseにすることで、
色は変わらず、カーソルが表示されない様になります。

 

偶然の結果ですが、
Panel1というのは、TDBCtrlGrid上に置いたことが、重要でした!!

最初は、Canvasの背景を描画して、
その上に、透明のTDBEditを置けばいいだろうとやっていたんですが、うまく行かず、

直接、TDBCtrlGrid.Colorを書き換えると、再描画が無限に行われますが、
TPanelのColorを書き換えてみたところ、うまく行きました。

 

APIでゴリゴリやろうかとも思っていましたが、
結果が同じなら、コード自体はシンプルな方がいいものです。

苦労した分、能書きが長くなりましたが(笑

 

PS.

あと、TDBEditの背景が透明にできるコンポーネントもあると、楽ですね。

>> 背景透明化可能 拡張エディット&メモ

DB非対応のTEditなのですが、TEdit > TDBEditと置き換えてやればいい。
※詳しくは、コンポーネントの作り方を学習してね

とやっていたのですが、
編集画面を作っている時に、落ち度が・・・ = ちゃんと描画されない

ので、
オリジナルのTDBEditに戻して、Panel1同様に、

    DBEdit.Color   := Panel1.Color;

を、足してやると、背景色が同色のまま、処理されます。

 

-