紅蓮のネタ帳

技術系の話を中心とした雑多なブログ

C#の.ToString()でハマった話

最近はお仕事でSQL Serverを弄りつつDelphiやったりC#やったりキーエンス独自言語やったりと色んな案件の仕事を振られている紅蓮です。
皆様いかがお過ごしでしょうか。

今回はC#のお話です。
C#初心者なので、.ToString()の説明もふわっと書いています。

C#の.ToString()は便利なメソッド

C#のだいたいの型には.ToString()メソッドが組み込まれており、これを呼んでしまえばオブジェクト型だろうがstring型に変換できるという優れもの。*1
型にもよるが、.ToString()が事実上の値取り出しのメソッドになっている場合もあり、stringに変換したあとの処理は実装次第で何とでもできるので何かと便利である。

引数指定でフォーマットを指定して変換できる

この.ToString()には引数を指定でき、引数でフォーマットの文字列を指定すれば変換の際に指定フォーマットで整形してくれる。
わざわざString.Format()を呼ばなくて済むので、ホントに至れり尽くせりのメソッドである。

書式を指定して数値を文字列に変換する - .NET Tips (VB.NET,C#...)

フォーマット指定に関してはVBC#開発者にはおなじみのdobon.netさんが参考になる
基本的に書式指定の方法はString.Format()と同じと考えて大丈夫だろう。

C#の.ToString()には、引数を受け付けてくれない型も存在する

今回の本題はここから。

プロジェクトで使用している.Net Frameworkのバージョンにもよると思われるが、.ToString()メソッドを使用する際に引数でフォーマットを指定するとコンパイルエラーが出る型が存在する。
このような型では、引数なしで呼び出す分には問題はないものの、フォーマットの文字列を指定して呼び出すと下記のようなエラーが出る。

引数を 1 個指定できる、メソッド 'ToString' のオーバーロードはありません

紅蓮はここでハマって2時間費やした。

問題が起きたのはDataTable型

お仕事の話に戻るが、先週C#の改修案件で回ってきたのがこんなものだった。

  • SQL Serverのストアドで取得したデータを帳票に出力するプログラムの改修(というかバグフィックス
  • ストアド側の設計がよろしくなく、小数点以下の数値が出る項目の小数点以下の桁数が統一されていない
  • ストアド側のSQLが複雑なので、ストアド側のアレな設計はとりあえず放置し、C#のクライアント側で表示桁数を調整する(先輩社員からそうするよう指示あり)

ストアド設計が悪いのが諸悪の根源であるのは言うまでもないが、C#のクライアント側もテストをちゃんとせずにリリースしちゃった感はある。
当時の担当者(退職済)はホントに何をしていたのやら。

実処理としてはDBから取得したデータをDataTable型に格納し、帳票出力用のフレームワークに文字列でセットする方式になっている。

DataTable型(正確に言うと、子オブジェクトのRows)には.ToString()が組み込まれており、元々の設計でも文字列への変換はこのメソッドでやっていた。
なぜか元々の処理は引数なしで.ToString()を呼び出していたので、前述のdobon.netさんなどの記事を参考に引数なしを入れてみることにしたが、入れたところコンパイルエラーが発生するようになった。

NGなコードサンプル

実コードをコピーしてここに貼るとコンプライアンス的によろしくないので、コンソールに出力するサンプルの処理を書いてみた。
DataTable.Rowsで引数を指定して.ToString()しようとすると、コンパイラに怒られる。

private void decimalFormatSample(DataTable sampleData) {

    for (int i = 0; i < sampleData.Rows.Count; i++) {
        
        //dataTableの.ToString()メソッドに引数を指定するとコンパイルエラー
        //引数を1個指定できる、メソッド'ToString'のオーバーロードはありません。
        Console.WriteLine(sampleData.Rows[i]["データ1"].ToString("0.00"));
        
    }
    
}

ちなみに、現環境の.Net Frameworkのバージョンは2.0。
互換性云々や大人の事情でこうなっているらしいが、化石のようなバージョンで動かしてるからこの手のエラーが出るのかもしれない。

.Net 4.x系じゃないと引数つきの.ToString()が動かない型もあるらしい

以下の記事はDataTable型ではないが、上記と同様のコンパイルエラー発生時の質問投稿に「.ToString()の引数指定に対応したのは.Net Framework 4.0から」といった回答がついている。

TimeSpanでのフォーマット指定方法: DOBON.NETプログラミング掲示板過去ログ

要するに、.ToString()の引数指定は昔からすべての型が対応していたわけではなく、.Net Frameworkのバージョンが新しくなるごとに拡張されていったということになるようだ。

.Netのバージョンを弄らずに対処する方法を考えてみた

どのみち、コンパイラのバージョンを勝手に弄るのは色々と問題があるので、それ以外の対処法を考えることになった。

冒頭でも言ったが、引数なしの.ToString()で文字列に変換してしまえば、あとは文字列をいじくり回すだけでなんとかなる。
その発想で処理を考えたところ、こうなった。

  • 一旦DataTableの中身を引数なしの.ToString()でstringに変換する(ここは改修前の処理と同じで、後続処理をしないと桁数が合わない状態)
  • stringからdecimalに変換して数値化する
  • decimalに対して.ToString()を引数付きで呼び出し、目的の桁数にフォーマットする

無駄が多いというか、エレガントさの欠片もない処理になってしまった。
decimal型は.Net 2.0でも引数ありの.ToString()を受け付けてくれるので、想定通りに変換が可能。

private void decimalFormatSample(DataTable sampleData) {

    for (int i = 0; i < sampleData.Rows.Count; i++) {
        
        //dataTableの.ToString()メソッドに引数を指定するとコンパイルエラー
        //引数を1個指定できる、メソッド'ToString'のオーバーロードはありません。
        //Console.WriteLine(sampleData.Rows[i]["データ1"].ToString("0.00"));
        
        //一旦decimal型に変換する
        decimal buf;
        buf = decimal.Parse(sampleData.Rows[i]["データ1"].ToString()); //引数指定なしの.ToString()はOK
        
        //decimal型から.ToString()する
        Console.WriteLine(buf.ToString("0.00"));
        
    }
    
}

今回のサンプルではFor文の中に変換処理を直接書いているが、実際に仕事で改修したプログラムでは、

  • For文の中で複数カラムの値を一気に取得する
  • ストアドを3つ回し、それぞれFor文でループ処理してデータを取り出す(取り出したデータはフレームワーク側で統合)

…といった元々の設計があったため、追加した変換処理の部分はフォーマット用の汎用関数として外部関数化する形をとった。

今回分かったこと・今後検証したいこと

分かったこと

  • .ToString()メソッドの引数指定ができない型がある
  • .Net Frameworkのバージョンが新しくなると、引数指定NGの型でも引数が指定できるようになる場合がある

検証したい事

  • .Net 4.xでDataTable型の.ToSring()の引数指定はできるのか
  • もうちょっとエレガントなフォーマット調整の方法はないか(C#の知識不足はあると思うので勉強したい)

今回色々調べてみて、C#もバージョンアップで機能追加されてるんだな、となんとなく分かったものの、お仕事の現場では常に最新バージョンを触れるとは限らないので、そのギャップとどう向き合っていくかは考えないとならない気はしている。

*1:中身がnullだと変換できないので、nullが想定される箇所ではきちんとnullのチェックをするお約束はある。

Azure SQL Database 月額料金表を実際に作ってみた

前回、Azure SQL Databaseの料金表の出し方と、それをもとに月額料金を計算した話を書いた。

glen.hatenablog.jp

記事の結びに「Excelとかで月額料金の表を作っとけば客先でも困らないね」と書いたが、善は急げで早速Excelにまとめてみた。
こういうの、忘れないうちにやっておかないと二度と着手しないヤツだと思うし。

 Azure SQL Database DTUモデル月額料金表

記事執筆時点のMicrosoft公式サイトの情報をもとに作成。
計算方法は前回記事を参照。

価格 - Azure SQL Database Single Database | Microsoft Azure

プラン DTU ストレージ DTU料金
カテゴリ 名称 付属容量 最大容量 毎時 月額平均
Basic B 5 2GB 2GB ¥0.7514 ¥549
Standard S0 10 250GB 250GB ¥2.2582 ¥1,648
Standard S1 20 250GB 250GB ¥4.5160 ¥3,297
Standard S2 50 250GB 250GB ¥11.2934 ¥8,244
Standard S3 100 250GB 1TB ¥22.5806 ¥16,484
Standard S4 200 250GB 1TB ¥45.1640 ¥32,970
Standard S6 400 250GB 1TB ¥90.3281 ¥65,940
Standard S7 800 250GB 1TB ¥180.6560 ¥131,879
Standard S9 1,600 250GB 1TB ¥361.3120 ¥263,758
Standard S12 3,000 250GB 1TB ¥677.4600 ¥494,546
Premium P1 125 500GB 1TB ¥70.0001 ¥51,100
Premium P2 250 500GB 1TB ¥140.0000 ¥102,200
Premium P4 500 500GB 1TB ¥280.0000 ¥204,400
Premium P6 1,000 500GB 1TB ¥560.0000 ¥408,800
Premium P11 1,750 4TB 4TB ¥1,053.7800 ¥769,259
Premium P15 4,000 4TB 4TB ¥2,408.5974 ¥1,758,276

※月額平均はうるう年を考慮せずに365日/年で計算し、小数点以下を四捨五入

上記表はいったんExcelにまとめた内容の転記となる。
お客様に見せることも考えて、Basic・Standard・Premiumのプランを1つの表にまとめてみるとこのようになった。

DTUの単価を見てもピンとこない人も多いだろうが、月額料金を並べるとAzureの料金はスペック次第でピンキリなのが分かるだろう。

なお、前回記事同様の注意点となるが、あくまでこの料金表は記事執筆時点の内容となる。
最新の料金はMicrosoft公式サイトで必ず確認してほしい。

 ベテランは月額料金も把握してたりする

この月額料金であるが、今いる会社ではベテラン社員中心に料金体系を暗記していて、客先や運用現場で何も見ずに、概算金額をパッと言える人もいたりする。
やはり、料金について何度も質問されたり、自分から話したりしたからだろうか。

実際に客先でPMが費用感を聞かれて即答したり、社内でも先輩社員から「テストDB(Standard S0プラン)は削除せずに放置してもだいたい月1,600円だからテストのたびにデプロイしなおすのは時間がもったいない」といった話が飛んで来たりと、すでに知識として定着している感はある。

ちなみに、今いる会社の費用感ではS0プランのテストDBは前述のように放置しても問題ないらしいが、S3プラン(S0プランの約10倍の価格)のテストDBを消さずに1週間近く放置したら別部署のPMから大目玉を食らったので、月額料金の目安はあったとしてもAzureは原則として時間課金と意識する必要はありそうだ。

Azure SQL Databaseの料金表の出し方と、月額いくらになるか計算した話

服薬でマシになってきたものの、相変わらず親知らずが痛い紅蓮です。
皆様いかがお過ごしでしょうか。

さて、今日はお仕事の話。
Azureの料金に関する話でございます。

Azureの料金、もしかして分かりにくい?

今いる会社でお客様に卸しているシステムの大半はMicrosoft Azure上にDBを構築しており、毎月のランニングコストとして、Azure利用料金はお客様に実費をご負担いただく形をとっている。

一応、事前に営業担当が費用に関してお客様に説明はするものの、後になって先方のシステム担当者から「月額いくらだっけ?」の話が出ることは割とあったりする。
そのやり取りの中で「MS公式サイトの料金表のページにたどり着けない」「結局、料金はいくらになるのか」といった質問も時々出てくるが、今回客先打ち合わせの際に、その場で料金表を開いて自力で試算を出すことになったので、やり方に関して備忘録を残しておきたい。

Microsoft公式の料金表の出し方

メール等での文字ベースのやり取りであれば、URLを載せる形で「ここを見てください」と言うこともできるし、それがベストプラクティスかもしれない。

しかし、お客様との打ち合わせの際に、プロジェクター投影をしているタイミングで「今、料金表を画面に出せませんか」と突然言われる可能性もゼロではないし、ブックマーク等がない環境でもMicrosoftの公式料金表の掲載ページへ行けるように手順を覚えておきたい。

Google検索結果からの料金表ページへの行き方

f:id:glenxar:20210516211601p:plain

Googleで「Azure 料金」と検索した結果

Google検索で「Azure 料金」と検索すると、検索結果上位にMicrosoftの公式ページが複数出てくると思う。
ここから料金表への動線がハッキリしていないのはMicrosoftのWebサイトの作り方がイマイチと言わざるを得ないが、文句を言っても仕方ないので、自力で料金表のページに進むことだけを考えたい。

  • 料金計算ツール
    Azureの各機能の料金を試算できる画面になっているが、デフォルトの設定から変更する必要があるパラメータが多く、まともに使える画面ではない。
    少なくともお客様にここを見るよう説明したら、確実に顰蹙を買うだろう。
  • 価格の概要
    Azureの各機能の価格表のページ(ここが正解)
  • 料金 - Windows Virtual Machine
    Azure VM(Virtual Machine)の料金ページ。Azure SQL DBの料金ではない。

今回は2番目の「価格の概要」を選ぶのが正解となる。
Googleの検索順序のロジックやMicrosoftSEO対策で順序は変わる可能性があるので、ページタイトルで覚えておいたほうが良いかもしれない。

Azureの価格一覧→Azure SQL Databaseの価格の行き方

f:id:glenxar:20210516213418p:plain

MSのAzure料金表ページ

Google検索から適切なリンクをたどると、Microsoft公式サイトのAzure料金のページに行くことができる。

この料金のページはあくまで各機能の料金のインデックスページといった位置付けで、目的のAzure機能の料金ページをこのページの中から探す必要がある。
そして、各機能のページへのリンクがある位置は、ページをスクロールした下部。フルFDの解像度でもリンクは隠れてしまっているので、必ずスクロールして探す必要がある。

f:id:glenxar:20210516214325p:plain

Azureの機能カテゴリ

ページ下部にスクロールすると、製品別の価格、要するにAzure各機能の価格のリンクが一覧になっている。
一覧画面は機能別にカテゴライズされているので、まずは画面左側のカテゴリから「データベース」を選択する。

なお、今回はたまたま「おすすめ」にAzure SQL Databaseが表示されているが、使用状況によってはAzure SQL Databaseが「おすすめ」の一覧に出ない場合があるため、カテゴリから表示する方法を覚えておくと吉。

f:id:glenxar:20210516215337p:plain

データベース系機能の一覧

データベースのカテゴリの一覧では、Azure SQL Databaseを選択する。
「DB」や「SQL」等の似通った名前の項目があるが、これらはすべて別物。

Azure SQL Database料金のページの操作方法

f:id:glenxar:20210516223900p:plain

Azure SQL Databaseの料金のページ

 上記のようにリンクをたどっていくと、Azure SQL Databaseの料金が掲載されたページにたどり着ける。
このページが今回の目的地となるが、価格一覧のページと同様にスクロールしないと料金表が出てこないうえに、パラメータを弄らないと適切な料金表が出てこないので、やはり一筋縄ではいかない。

f:id:glenxar:20210516225022p:plain

価格オプションの設定

最初の表示画面から少し下にスクロールすると、「価格オプションの詳細」でパラメータを変更する欄が出てくる。
設定は下記の通り。

  • 「Single Database」と「エラスティックプール」のタブがあるが、デフォルトのSingle Databaseを選択したままにする。
  • パラメータの一番左上にある「購入モデル」のパラメータを「vCore」→「DTU」に変更する。
  • それ以外のパラメータは変更せず、初期値のままにする。

パラメータを弄るのは購入モデルの1ヶ所で、それ以外はデフォルト値でOK。

ちなみに、購入モデルに関してざっくり解説すると、vCoreはサーバーのCPUコア数・メモリ容量などを手動で設定する方式で、DTUはMicrosoft側が準備したCPUコア数・メモリ容量などの組み合わせのプリセットを選択する方式となっている。

性能面は設定次第となるが、価格面ではDTUモデルが総じてvCoreモデルよりもコストパフォーマンスが上回るようになっている。
要するに、vCoreモデルは高価ということ。

例外的に一部条件下ではvCoreモデルのほうが安価で運用できることもあるが、通常用途ではDTUモデルでの料金設定としたほうが有利な場合が多い。

f:id:glenxar:20210516230056p:plain

DTUモデルの料金表

ここまでの操作をすると、DTUモデルの公式な価格表を見ることができる。
スクリーンショットの画像は記事執筆時点での内容なので、必ず最新の内容は確認してほしい。

この表に載っているDTUの料金はDB稼働1時間ごとの基本料金で、DTUに付属しているストレージ容量を超えて使用する場合、ストレージを増やした分の料金が課金される。

月額料金の出し方

Microsoft公式の料金表は、DTUの1時間あたりの料金しか書かれてない。
この表を見て、お客様から「結局毎月いくらになるの?」といった質問が出てくるパターンもあるだろう。

月額料金の計算式

表に載っているのは1時間あたりの料金なので、それに24をかけて1日あたりの料金を出し、その月の日数をかければ月額料金を算出できる。
月額の平均を出したい場合は、年額を出してから12で割ればよい。

  • 月額料金(単月)
    DTU料金×24時間×該当月の日数
  • 月額料金(平均)
    DTU料金×24時間×該当年の日数÷12ヶ月

例えば、Standard S3プランでDBを稼働させた場合、記事執筆時点でDTU料金は22.5806円となっている。

上記計算式で計算すると、月額料金は以下のようになる。

  • 2021年5月料金
    22.5806×24×31=16,799.9664円
  • 2021年月額平均
    22.5806×24×365÷12=16,483.838円

手間にはなると思うが、事前にExcel等でDTUの料金をまとめておき、上記計算を済ませた料金表を作っておけば、お客様との打ち合わせがスムーズになるかもしれない。

液晶ディスプレイ買いました

f:id:glenxar:20210513222335j:plain

おニューの液晶ディスプレイ

智歯周囲炎(親知らず周辺の歯茎の腫れ)の影響で寝不足気味の紅蓮です。
皆様いかがお過ごしでしょうか。

今回は題目の通り、液晶ディスプレイを買った話でございます。

楽天で特価品を見つけました

今回買ったのは、I-O DATAのKH240V。

同じようなサムネでDIOS-LDH241DB、EX-LDH241DBといった別品番もあるが、これは販路によって型番が違うというもの。
ラインナップとしては下記のようになるらしい。

  • KH240V:特定販路専用品(恐らくビックカメラグループ専売)
  • EX-LDH241DB:Amazon専売モデル
  • DIOS-LDH241DB:EC専用モデル(上記以外の販路)

販路によって値段にだいぶバラツキがあり、市価はおおよそ16,000~18,000円台となっている。

f:id:glenxar:20210513223708j:plain

コジマで特価になっていた

探してみると15,000円を切っている店があった。なんと、コジマである。
親会社のビックカメラ本体(楽天市場店)が16,200円の市価通りの販売なので、価格面はかなり頑張っていると思う。

ちなみに、今月末が期限の楽天の期間限定ポイントが1,500円前後あったので、ポイント消化でキリの良い13,000円ポッキリで購入することにした。
期間限定ポイントの分もあるとはいえ、13,000円だと海外メーカーの機種しか買えないので、良い買い物をしたとは思う。

早速入れ替えてみた

f:id:glenxar:20210513224527j:plain

旧ディスプレイ(LG 21.5インチIPSパネル

元々、自宅PCでは21.5インチの液晶を使っていた。
このサイズでも家でやるレベルの作業の作業に支障は出ないが、会社のPCの24インチの液晶に慣れてしまい、21.5インチでは満足できないカラダになってしまったのです。

f:id:glenxar:20210513225005j:plain

新ディスプレイ(I-O DATA 23.8インチADSパネル)

楽天で特価になっていたのも購入理由の一つだが、商品写真を見て「台座が低そう」なのが一番の購入の決め手となった。

ディスプレイ上端部の位置も21.5インチのときとそこまで変わらないので、画面が大きくなってもそこまで違和感は出ていない。

付属品は充実

取説と付属品

f:id:glenxar:20210513225614j:plain

取扱説明書

海外メーカーの機種だと付属はVGAケーブルのみの場合もけっこうあるが、I-O DATAのディスプレイはHDMIケーブル・VGAケーブル・オーディオケーブル(3.5mmジャック用)と至れり尽くせりである。
基本的にHDMIVGAのどちらもついていないPCはほとんどないと思うので、わざわざケーブルを買わなくてもいいのはありがたいところ。

HDMIの音声出力を試してみたが…

ディスプレイにはスピーカーがついているものの、音質はお察しください。
この手の内蔵スピーカーで音が良かった試しがないので最初から期待はしてなかったけど、こだわるならちゃんとしたスピーカーは準備したほうがよさそう。

設定関連は若干ポンコツ

メニュー階層は以下のようになっている。

  • 入力切替
  • 音量
  • 輝度
  • メニュー

入力切替/音量/輝度設定は説明するまでもないので割愛する。

f:id:glenxar:20210513230647j:plain

メニュー

メニューの中には、予めショートカットとしてコントラスト・色温度の設定が入っている。
基本的にこの2つの設定をすればいい感じに使えるようになるが、コントラストはデフォルトのままが一番見やすい。この辺の調整は流石といったところ。

色温度のプリセットが残念

f:id:glenxar:20210513231554j:plain

色温度の設定画面

 色温度は6500K/7200K/9300Kがプリセットされているが、プリセットの設定はどれもしっくりこない。

デフォルトの6500Kが「自然な白色が表現できます」となっているが、個人的に6500Kの設定は黄色っぽさが強くてダメだった。
9300Kは論外。

真ん中の7200Kがプリセットの中では一番マシだが、なんかコレジャナイ感じ。
結局ユーザー設定でRGBを調整することになったが、キャリブレーションに関してはプリセットが有効に使えないと思った方が良い。ちょっと上級者向け。

便利機能はメインメニューの中に

f:id:glenxar:20210513232857j:plain

メインメニュー

商品説明でウリになっているような機能は基本的にメインメニューの中に入っている。
画面の反応速度を上げる等、弄ると便利な項目が多いが、如何せんメニュー階層が深いのでたどり着くまでが結構めんどくさい。

初心者向けの設定機能としては画面モードのプリセット設定(色温度コントラスト等をまとめて行える)があるが、この設定項目はショートカットに入っておらず、メニューの奥の方まで行かないと弄れない。
ショートカットの3番が空いてるので、デフォルトでこの項目に飛べるようにしといたほうが良いんじゃないのかな~とは思った。

総評

設定がちょっとめんどくさい部分はあるが、一度設定してしてしまえばかなり快適に使える製品であるとは思う。
標準の反応速度でも、会社のAcer製ディスプレイにあるような残像感はほとんどないし、ディスプレイとしての基礎的な部分は良くできていると思う。

以前、BENQのディスプレイを使ってた時にパソコンから設定を弄れるソフトが付属していたが、他社でもそういう機能がついたりしないだろうか。

ブログ開設しました

テスト投稿です。

ブログ開設目的

  • Twitterでの長文投稿がつらくなってきたので、ブログに書いた方が良いんじゃないかと思いました。
  • 技術系のネタを中心に備忘録的なものをそろそろ作っておいたほうが良いんじゃないかと思いました。

開設してみた所感

  • Twitterのフォロワーさんから「バズり重視ならQiita、お手軽さならはてブ」とのアドバイスをもらったのでこちらにしました。
    バズりは別にいらないしなぁ…
  • 開設にかかった時間は20分程度でした。
    • 登録はメールアドレスと希望ID・パスワードをを入れて認証するだけ。
      わ~いらくち~ん!
    • 設定はプロフィールをちょこっと弄った程度。
    • ブラウザのCookie関連の設定を弄ってみたものの、結局「サードパーティーCookieがブロックされています」の表示は消えませんでした。
      ChomeだとCookieをブロックしない設定でもこの表示が出る場合があるとのことで、もしかしたらはてブ側の実装がよろしくないのかも。うーむ。
  • イマドキのブログ、Markdownで編集できるんですね。
    • 仕事でMarkdownを使うようになったので、Markdownの文法の練習兼ねてしばらくはMarkdownで投稿してみようと思います。
    • VSCodeと同じようなリアルタイムプレビューもついてるのはいいですね。
    • Web画面の仕様として、箇条書きのインデントは手動(スペースキー連打)で行う必要がある等の制限があるようです。
      VSCodeMarkdown弄るときの癖でTabキーを押すと悲しいことになります。
    • 何も考えずにMarkdownで書くと箇条書きばっかになりそうなので、もしかしたらブログ書く場合は通常編集モードのほうが良いのかも…?