エクセルテーブルをデータ入力規則リストに使う

エクセルでプルダウンメニューから選択して入力するにはデータ入力規則でリスト入力設定にすればよい。リストの元の値(Source)にテーブルを指定すれば選択肢数を増減させても即選択肢に反映されるので柔軟に扱える。

設定するには3ステップを行う。

  1. テーブルの作成
  2. テーブル名の設定 ※省略可
  3. プルダウンメニュー化範囲にデータ入力規則を設定 ※ドロップダウンリストとも呼ばれる

1.テーブルの作成

図1.テーブル化

テーブル化するデータを入力してから、範囲を選択(図1のA1:B4)→メニュー『挿入』タブの『テーブル』を選択

図2.テーブルの作成

適宜『先頭行をテーブルの見出しとして使用する』にチェックを入れて、『OK』ボタンを選択

図3.テーブル化完了

2.テーブル名の設定

図4.テーブル名の変更

テーブル選択状態で、メニュー『テーブルデザイン』タブの『テーブル名:』で適宜テーブル名を変更する

※デフォルトの名前がついているのでテーブル名設定は省略出来るが、後で分かりやすいので変更推奨

図5.テーブル名を食べ物に変更した

3.プルダウンメニュー化範囲にデータ入力規則を設定

図6.データ入力規則

プルダウンメニューから選びたい範囲を選択後、メニュー『データ』タブの『データの入力規則』を選択

図7.データの入力規則の設定

『入力値の種類:』は『リスト』に変更し、『元の値:』は『=INDIRECT(“テーブル名[列名]”)』の書き方にして『OK』を選択。

※この例では元の値は=INDIRECT(“食べ物[フルーツ]”)=INDIRECT(“食べ物[やさい]”) となる。テーブルの定義に合うよう適宜変更する

※INDIRECTを省略したりダブルクォーテーション記号を省略したりすると正常に動作しないから注意して入力する

図8.プルダウンメニューから選択可能

SQLiteをVisual Basic .NET で使う

Visuual Basic .NET(VS .NET 2019, .NET Core 3.1)環境でSQLite3を使った。

  • SQLite3 関連のNuGetライブラリは乱立していて依存関係は複雑
  • 検索ではC#の記事が多く直接VB .NETで使えない

であったため備忘録を残す。

1.依存ライブラリのインストール

Visual Studio のメニューから『ツール→NuGetパッケージマネージャ→ソリューションのNuGetパッケージの管理 』を辿り、『sqlite-net-pcl』で検索してインストールする

※このライブラリは他に依存関係ダウンロードはなくとも正常に動作した

2.クラスの作成

メニューの『プロジェクト→クラスの追加』でTestTable.vb というデータ格納用のテーブルを作成する。

Imports SQLite
Public Class TestTable
<AutoIncrement, PrimaryKey>
Public Property id As Integer
Public Property description As String
Public Sub New(description As String)
_description = description
End Sub
Public Sub New() ‘引数なしのコンストラクタが必要
End Sub
End Class

気になるのは2点。

2.1.<AutoIncrement, PrimaryKey>の部分

SQLiteのDB向けアノテーションで、id フィールドがAutoIncrement, Primary Keyと手軽に設定出来てしまうので便利だ。

2.2.Public Sub New()の部分

引数を持たないPublic Sub Newの定義は必須となっている。SQLiteが自動的にインスタンスを生成するのに要る様子

3.DB・テーブル作成、INSERT、UPDATE、DELETE、SELECT

GUI上でボタンを作成し、ダブルクリックで後述の関数(ButtonDebug_Click)の中身を実装する。デモとして用意したボタンクリック時の処理フローは以下の通り。

3.1.ボタンクリック時の処理フロー

  1. Test.db DBを作成する
  2. テーブルを作成する
  3. 20件レコードINSERT
  4. ID>10のレコードのみ取得し、IDが5の倍数なら削除 or descriptionの末尾に”Updated”を付与する
  5. データ全件SELECT・出力

3.2.関数の中身

Private Sub ButtonDebug_Click(sender As Object, e As EventArgs) Handles ButtonDebug.Click
‘1.Test.db DBを作成する
Using connection = New SQLiteConnection(“Test.db”)
‘2.テーブルを作成する
connection.CreateTable(Of TestTable)()
‘3.20件レコードINSERT
For i As Integer = 1 To 20
Dim NewItem = New TestTable(“description” & i)
connection.Insert(NewItem)
Next
‘4.ID>10のレコードのみ取得し、IDが5の倍数なら削除 or descriptionの末尾に”Updated”を付与する
Dim Items = connection.Table(Of TestTable)().Where(Function(x) x.id > 10)
For Each Item In Items
If Item.id Mod 5 = 0 Then
‘IDが5の倍数の場合削除
connection.Delete(Item)
Debug.WriteLine(“DELETE: id:{0}”, Item.id)
Else
‘IDが5の倍数でなければ更新する
Item.description = Item.description & “Updated”
connection.Update(Item)
Debug.WriteLine(“UPDATE: id:{0}”, Item.id)
End If
Next
‘5.データ全件SELECT・出力
Items = connection.Table(Of TestTable)()
For Each Item In Items
Debug.WriteLine(“SELECT: id:{0}, description:{1}”, Item.id, Item.description)
Next
Debug.WriteLine(“done”)
End Using
End Sub

  • Test.db を指定している部分でDBファイル名を指定
  • CreateTableで型を指定すればその型のDBテーブルが生成される
  • インスタンスを引数に設定してInsert/Update/Deleteを呼び出せば手軽にレコードのCUDが可能
  • SELECTは更に簡単で、LinqでTable(Of ClassName)() を扱えば良い。ただし『WHEREでMod』のような条件は不可

SQLなしで手軽に作れるのがやりやすくて便利。※SQLで取得したい場合は以下のように取得すればよい

Dim x = connection.Query(Of TestTable)(“SELECT * FROM TestTable WHERE description=?”, “QueryCondition”)

3.3.実行結果出力

UPDATE: id:11
UPDATE: id:12
UPDATE: id:13
UPDATE: id:14
DELETE: id:15
UPDATE: id:16
UPDATE: id:17
UPDATE: id:18
UPDATE: id:19
DELETE: id:20
SELECT: id:1, description:description1
SELECT: id:2, description:description2
SELECT: id:3, description:description3
SELECT: id:4, description:description4
SELECT: id:5, description:description5
SELECT: id:6, description:description6
SELECT: id:7, description:description7
SELECT: id:8, description:description8
SELECT: id:9, description:description9
SELECT: id:10, description:description10
SELECT: id:11, description:description11Updated
SELECT: id:12, description:description12Updated
SELECT: id:13, description:description13Updated
SELECT: id:14, description:description14Updated
SELECT: id:16, description:description16Updated
SELECT: id:17, description:description17Updated
SELECT: id:18, description:description18Updated
SELECT: id:19, description:description19Updated
done

予定通りID:11~20のうち15,20のみDELETEされた

結果としてID:11~14,16~19のdescriptionにUpdatedが付与された

⇒想定通りの動作

C#.NETでのSSL証明書情報取得方法

2021年8月時点、C# .NETでのモダンなSSL証明書情報(URL, 署名者, 期限日等)取得方法について調査した。

結論的には.NET Core ではServicePoint.Certificateは使えなくなっているため、HttpClientHandler.ServerCertificateCustomValidationCallbackを用いて取得する。

確認環境

.NET Core 3.1 on Windows 10

正常動作するコード

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;

namespace GetExpirationDateTest
{
class Program
{
static void Main(string[] args)
{
List tasks = new List();
tasks.Add(Task.Run(() => GetExpirationDate(@”https://example.com/”)));
//tasks.Add(Task.Run(() => GetExpirationDate(@”https://example.com/”)));
Task.WhenAll(tasks);
Console.WriteLine(@”DONE”);
string sign = Console.ReadLine();
}

    static async Task GetExpirationDate(string url)
    {
        Console.WriteLine(url);

        // Create an HttpClientHandler object and set to use default credentials
        HttpClientHandler handler = new HttpClientHandler();

        // Set custom server validation callback
        handler.ServerCertificateCustomValidationCallback = ServerCertificateCustomValidation;

        // Create an HttpClient object
        HttpClient client = new HttpClient(handler);

        // Call asynchronous network methods in a try/catch block to handle exceptions
        try
        {
            HttpResponseMessage response = await client.GetAsync(url);

            response.EnsureSuccessStatusCode();

            string responseBody = await response.Content.ReadAsStringAsync();
            Console.WriteLine($"Read {responseBody.Length} characters");
        }
        catch (HttpRequestException e)
        {
            Console.WriteLine("\nException Caught!");
            Console.WriteLine($"Message: {e.Message} ");
        }

        // Need to call dispose on the HttpClient and HttpClientHandler objects
        // when done using them, so the app doesn't leak resources
        handler.Dispose();
        client.Dispose();
    }

    private static bool ServerCertificateCustomValidation(HttpRequestMessage requestMessage, X509Certificate2 certificate, X509Chain chain, SslPolicyErrors sslErrors)
    {
        // It is possible inpect the certificate provided by server
        Console.WriteLine($"Requested URI: {requestMessage.RequestUri}");
        Console.WriteLine($"Effective date: {certificate.GetEffectiveDateString()}");
        Console.WriteLine($"Exp date: {certificate.GetExpirationDateString()}");
        Console.WriteLine($"Issuer: {certificate.Issuer}");
        Console.WriteLine($"Subject: {certificate.Subject}");

        // Based on the custom logic it is possible to decide whether the client considers certificate valid or not
        Console.WriteLine($"Errors: {sslErrors}");
        return sslErrors == SslPolicyErrors.None;
    }
}

}

参考URL:

ServicePoint.Certificate プロパティ – .NET Core では常にnullになり使えないと言及

https://docs.microsoft.com/ja-jp/dotnet/api/system.net.servicepoint.certificate?view=net-5.0

HttpClientHandler.ServerCertificateCustomValidationCallback プロパティ – 使用サンプルあり

https://docs.microsoft.com/ja-jp/dotnet/api/system.net.http.httpclienthandler.servercertificatecustomvalidationcallback?view=net-5.0