Xojo でユーザがロジックを変更しやすくするために

得点をチェックして、赤点なら赤文字にする処理。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/7a1fe8d8-d47d-58dc-4565-344b9b683927.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9a96674e-fef2-b54d-7fec-f325eb1e4558.png)
この、赤文字にする処理は CheckListBox1 メソッドに書かれている。
```
For row As Integer = 1 To ListBox1.RowCount - 1
  if ( 30 >= Listbox1.Cell(row, 0).ToInteger ) then
    ListBox1.CellStyle(row,0) = WebStyleTextRed
  end if
Next

```
この処理だけど、赤点の基準が都度都度変わときにどうするのがいいかな?

上のコードでは `30 >= Listbox1.Cell(row, 0).ToInteger ` ということで30点以下なら赤文字にする。ハードコーディングしているけど、利用者が簡単に変更できるように考えたい。

1. DB に判定値を入力し、それを参照するようにする。
2. 外部ファイルに判定値を書き込み、それを参照するようにする。
3. 外部ライブラリにする

まともに考えるなら1. または 2.。 しかしながら得点のしきい値だけではなく、赤点判定のロジックも変わるとするとどうなるか?

1. DBに判定クエリを登録し、それを呼び出す
1. 判定を外部ライブラリで行う
1. 外部ライブラリにする

ここでは、このような場合に外部ライブラリにして、利用者が簡単に変更できるようになるかどうか考えてみます。

# 環境

- Xojo 2019 Ver3.2 (Web1.0 ベースの 旧Xojo)
- Webアプリ(スタンドアローン ないし デバッグ実行)
- Windows10 Pro 上でIDEを使用

# メソッドを外部ライブラリ化する

「Insert」のアイコンを押し「Module」を選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5202b402-9d6a-cd6c-59c8-7855e2e1ccd1.png)
「CheckListBox1」メソッドを を 「Module1」 に移動し、「CheckListBox1」 内部の ListBox1 への参照を書き換える
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/0f2aeef4-eace-886f-375f-3d0b820ab800.png)

「Module1」の名前をわかりやすいように「外部モジュール1」に変更しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/df2f6b70-75b8-6950-62d4-8d75ff0a3d59.png)

メソッドの呼び出し元を書き換えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e31787c6-641c-67fa-9aa2-c9635bc3c45c.png)

「外部モジュール1」を外部モジュールに変換します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/7a9e7263-d95f-b22b-ece4-02fc3f6f7622.png)

XML形式で保存すれば、ユーザサイドで変更できるかどうかな?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/bdbef197-c904-bb66-97c6-48b312ba7367.png)

「外部モジュール1」の表示が斜体になり、外部モジュールになっていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5a7719bb-48ec-acfe-5eac-da54d7882677.png)

外部モジュール中のメソッドのScopeをGlobalに変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/63dfb377-25fb-b875-02a2-2b2ba853a86b.png)

ここで、「外部モジュール1.xojo_xml_code」として保管されたファイルの中身は以下のようになっています。

```
<?xml version="1.0" encoding="UTF-8"?>
<RBProject version="2019r3.2" FormatVersion="2" MinIDEVersion="20110400">
<block type="Module" ID="598937599">
 <ObjName>外部モジュール1</ObjName>
 <ObjContainerID>0</ObjContainerID>
 <IsClass>0</IsClass>
 <ItemFlags>1</ItemFlags>
 <IsInterface>0</IsInterface>
 <Compatibility></Compatibility>
 <Method>
  <ItemName>CheckListBox1</ItemName>
  <Compatibility></Compatibility>
  <Visible>1</Visible>
  <PartID>104853503</PartID>
  <ItemSource>
   <TextEncoding>134217984</TextEncoding>
   <SourceLine>Sub CheckListBox1()</SourceLine>
   <SourceLine>For row As Integer = 1 To WebPage1.ListBox1.RowCount - 1</SourceLine>
   <SourceLine>if ( 30 &gt;= WebPage1.Listbox1.Cell(row, 0).ToInteger ) then</SourceLine>
   <SourceLine>Webpage1.ListBox1.CellStyle(row,0) = WebStyleTextRed</SourceLine>
   <SourceLine>end if</SourceLine>
   <SourceLine>Next</SourceLine>
   <SourceLine>End Sub</SourceLine>
  </ItemSource>
  <TextEncoding>134217984</TextEncoding>
  <AliasName></AliasName>
  <ItemFlags>33</ItemFlags>
  <IsShared>0</IsShared>
  <ItemParams></ItemParams>
  <ItemResult></ItemResult>
 </Method>
 <ViewBehavior>
  <ViewProperty>
   <ObjName>Name</ObjName>
   <Visible>1</Visible>
   <PropertyGroup>ID</PropertyGroup>
   <ItemType>String</ItemType>
  </ViewProperty>
  <ViewProperty>
   <ObjName>Index</ObjName>
   <Visible>1</Visible>
   <PropertyGroup>ID</PropertyGroup>
   <PropertyValue>-2147483648</PropertyValue>
   <ItemType>Integer</ItemType>
  </ViewProperty>
  <ViewProperty>
   <ObjName>Super</ObjName>
   <Visible>1</Visible>
   <PropertyGroup>ID</PropertyGroup>
   <ItemType>String</ItemType>
  </ViewProperty>
  <ViewProperty>
   <ObjName>Left</ObjName>
   <Visible>1</Visible>
   <PropertyGroup>Position</PropertyGroup>
   <PropertyValue>0</PropertyValue>
   <ItemType>Integer</ItemType>
  </ViewProperty>
  <ViewProperty>
   <ObjName>Top</ObjName>
   <Visible>1</Visible>
   <PropertyGroup>Position</PropertyGroup>
   <PropertyValue>0</PropertyValue>
   <ItemType>Integer</ItemType>
  </ViewProperty>
 </ViewBehavior>
</block>
</RBProject>

```
これを編集してみるとどうなるでしょうか? Xojo を終了したあと、メモ帳で書き換えてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/061773c4-369a-8acf-d01a-1a928a284b70.png)

再度開くと変更が反映されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/8b64e729-b4a8-5eaa-3249-fe23a5825d0f.png)

実行するとしきい値変更が有効なことがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a1c1e924-c5c4-095e-4774-635f078da51e.png)

# Xojo Code形式のライブラリファイルをエクスポートで作ろうとしてみる

先のやりかたでは、ライブラリファイルは 「Xojo Binary Code」 と 「Xojo XML Code」 しか選ぶことができませんでした。 XML形式を直接書き換えるよりも、「Xojo Code」形式のコードが編集しやすいので、ライブラリファイルをテキスト形式にできるかどうか挑戦してみます。 

先に作った「外部モジュール1」 を、 Export してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5f4caa2d-0db7-a3d2-61aa-9394d48f84d5.png)
ここでは 「Xojo Code」が選べるのですが、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e49f0e76-aeaa-37e0-efb5-7fef7f777fe3.png)
エクスポートしようとするとエラーが出でできませんでした。うーむ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/22dafa8b-e78f-4c0d-1362-bacd28f0d7db.png)
# Xojo Code形式のライブラリファイルもどきを作成してみる

仕方がないので別の方法を試します。
新しい、Webアプリケーションを作ります。デフォルトでできる「WebpPage1」コンテナを「library1」名に変更します。そこに「CheckListBox1」メソッドを作ります。先に作った「CheckListBox1」をドラッグ&ドロップで作りました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/8e956f47-f180-3fdc-d943-eef2280f7a28.png)

library1.xojo_project として保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/6a122f42-1276-7558-28c5-c425c730b821.png)

library1.xojo_code ファイルが生成されます。
中身はこのようになっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/7f8c5c04-6743-28d6-26c5-fa79df358466.png)
このファイルを、使用したいプログラムにドラッグ&ドロップします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/64eeb244-fff2-b80e-a4b4-bb3ed095d3cc.png)
呼び出し元を変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/f144b7b2-9c15-fb4b-7637-9d2d8d660d37.png)
これで動作しますが、この読み込んだ library1.xojo_code はどうなるでしょう?

プログラムをXojo Code形式で保存すると保存ディレクトリに library1.xojo_code が生成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/26dc8f3c-64b0-a7fb-abda-3f5cd4a71fbf.png)


これはドラッグ & ドロップした library1.xojo_code とは別のものです。プログラムの保存場所を元の library1.xojo_code と同じ場所にすると、元のファイルと共用できます。しかしながらその場合はその他のファイルの名前が衝突しないように注意しないといけません。

# ビルド時の library1.xojo_code 

Webアプリとしてスタンドアローンとしてビルドします。
ここで、他の種類のファイルもドラッグ&ドロップでビルドに含めてみます。dbaccess.json を library1.xojo_code と共にドラッグ&ドロップしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/7b5eb0e8-adb2-f777-fe73-88c61b363239.png)

ビルドしてできたファイルです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/952f79ad-b3ee-1d54-cabd-c4ad6e98e0fa.png)
ここで、dbaccess.json ファイルは 「test Resources」に含まれていますが、library1.xojo_code は含まれていません。含まれていたならビルドせずにコードを入れ替えることができたのですがそのようなことはできなさそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/91e9bdbf-5617-2b30-98b3-41ce43efbbfa.png)

こちらは「test Libs」の内部です。library1.xojo_code が DLL 化されているわけでもなさそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/869f058b-b96e-1f63-7af4-31804b0c32c3.png)



# 結論 

 Xojo コードに手を加える変更 → 手を加えるコードをライブラリ化し、xml 形式で外部ファイルにするか、Xojo code 形式でファイルを分けて管理

 Xojo コードに手を加えない変更 → コードのライブラリ以外の方法を使う