2019年6月13日木曜日

配列が空かどうかを調べるのに、自作の関数を実装するなんて、わざと凝ったつ くりで自己満足するだけよ - VBA・Split関数(そのほか)

Split関数ならぬ、スプリット変化球の握り

前回の投稿では、セル内で改行されたデータを置換するのに工夫してみました。
コードの動きも繰り返しで実験して、Split関数の吐き出す配列で確認したのよ。

コード的には、置換の文言とループ関数で取得したセル値の文言を比較します。
ただ、何もデータのない空白セルだけは、If構文で特定することにしました。

Dim Cll As Range
For Each Cll in Selection
If Cll.Value = "" Then GoTo EndTsk
~そうでない時に、配列が合うか比較するコード~
End Tsk
Next Cll

そのロジック部分を抜き出すと上の通りですが、詳細は前の投稿を参考下さい。
GoToステートメントを使って、条件外になると次のステップを飛ばす算段です。

本当は、Split関数で条件の配列と比較する配列が、完全に比較できると思った。
ところが、ターゲットのセル値が空白だと配列が比較できずに置換してしまう。

実験用のシートが、一面で置き換わってしまって、これはいかんと思いました。
なのでセル値が空であれば、シンプルに無駄な作業をスキップさせてみました。

コードの動きを何度か実証してみましたけれど、実用範囲だからOKでしょう。
ただ、空白セルでSplit関数がどのような結果を吐き出すのか、よく分からない。

ネットで調べてみましたが、配列が空なのかどうかを調べる関数はないらしい。
変数が配列なのかを調べる関数(IsArray)はありますが、配列を作った結果だ。

だから、この関数による結果が、空の配列であっても結果的には"True”になる。
ならば、空の配列なら値が無いと思い、IsEmpty関数で確認しても結果が違う。

Split関数は、配列の要素順番が、LBbound(開始値)UBound(最終値)です。
でも、IsEmptyにぶち込んでも、”False”とでるので空とは認識していなさそう。

    Dim tmp As Variant
    tmp = Split(Cells(1, 1), Chr(10)) ’空白セル・区切り文字は改行コード
    If IsEmpty(LBound(tmp)) = "True" Then MsgBox "True"
    If IsEmpty(LBound(tmp)) = "False" Then MsgBox "False"

となれば、Split関数は区切文字が見つからなくても 配列はでっち上げるんだ。
これが分かっただけでも御の字で、ネットを当たると自作関数を紹介するほど。

Functionプロシージャを設定する説明だったけど、もっと簡単じゃないのか。
そう思って、どんな開始と最終の値を出力するか、しつこく調べてみたんだよ。

Dim tmp As Variant
tmp = Split(Cells(1, 1), ”※”) ’区切り文字は”※”
If UBound(tmp) = -1 And LBound(tmp) = 0 Then MsgBox "空のセル"
If UBound(tmp) = 0 And LBound(tmp) = 0 Then MsgBox "区切文字無し"
If Len(Cells(1, 1)) > 0 And InStr(Cells(1, 1), ”※”) = 1 Then MsgBox "先頭が区切文字"
If Len(Cells(1, 1)) > 1 And Len(Cells(1, 1)) = InStrRev(Cells(1, 1), ”※”) Then MsgBox "末尾が区切文字"

  
シートの先頭セルに、メッセージボックスにある条件で入力してみてください。
一番目のIf文は空白セルの場合、二つ目はデータに区切文字が見当たらない。

三番目は、末尾が区切文字で、四番目は、先頭が区切り文字になるという事例。
まあ、三番目と四番目は、区切文字が入っているセルなので配列には違いない。

このため、字数を調べて区切り文字が先頭か末尾かを条件式で判断しています。
まあ、四つの条件を満たすセルの内容は、作業をスキップしまえばいいんだ。

つまり、この関数は区切文字でデータを仕切ることしか想定していないような。
というわけで、区切る位置がイレギュラーな場合を想定しない関数なのでした。

実際、この関数を使うとしたら、区切り文字で要素に配分してから、必要な配列順番のデータを取得して、次の作業ステップに移行しますが、先頭に区切り文字が出るようなケースは、データの羅列として考えられそうもなく、ありえるのはデータ末尾に区切り文字が入ってしまうことぐらいでして、そういう事例はプログラミングの工夫で操作も出来そうだと思ったのでした。

おまけ:
とてもイレギュラーだけど、セルの値が複数の区切り文字だけだとしたら、、、
   
Dim i As Long
Dim tmp As Variant
   
i = 0
tmp = Split(Cells(1, 1), "※")
   
Do While i < UBound(tmp) + 1
If Not tmp(i) = "" Then GoTo WithData
i = i + 1
Loop
   
MsgBox "要素が空"
GoTo Finish
   
WithData: MsgBox "要素が存在"
Finish:
   
End Sub
   
   
コメント:結果は、”要素が空”と表示。一個でも文字が挟まっていると存在。



いいねと思ったら、三つポチっとね!
にほんブログ村 スキースノボーブログへにほんブログ村 スキースノボーブログ スキーへにほんブログ村 旅行ブログ 旅日記・旅の思い出へ
にほんブログ村    にほんブログ村      にほんブログ村 



2019年6月10日月曜日

エクセルのシートで、改行された文字データのセルを上手に置換できるVBAのプログラムを書いたのでござる - VBAマクロ(そのほか)

  
最近、社内で使われるプロトコルのマニュアルを、英語に翻訳して疲れました。
プロトコルは通信制御手段とも言われますが、分かったようで分からない言葉。

仮に身近にある道具を使って説明するなら、USBでデータのやり取りでしょう。
USBメモリーを、パソコンに指してデータを移動させるのは、当たり前なんだ。

それで、ソケットを見ると四つの接続端子しかなくて、しかも二つは電源供給。
となると、データ通信はたったの線二本でしか行われていないことになります。

そうなると、この二本でデータを上手く受け流すには、制御ルールが必要なの。
これが通信制御手段で、英語で格好良くプロトコルって言うだけの話なのです。

ユニバーサル・シリアル・バスは頭文字からUSBなんだけど、通信規格の一つ。
コンピュータの内外から、各回路がデータ交換で共通の経路を使うのに必要だ。

コンピュータ用語ですが、有線だろうが無線の5Gだろうが通信は規格が重要。
このコミュニケーションのしきたりがちゃんとできないと、機械は村八分状態。

勤務する会社が扱う製品も、サーバーと通信できなければ、ただのハコ扱いよ。
だから、システム開発をする上で、きちんとプロトコルを理解してもらいます。

お客さんに提供するマニュアルも揃えますが、海外の顧客が出始めてきました。
このため、是が非にでも英語化する必要に迫られたのか、支援を頼まれました。

    
それで、上記のようなマニュアルに訳しましたが、技術用語の繰り返しが多い。
エクセルで作られているので”置換”の操作もできますが、一つ困りごとが発生。

それは、一つのセルの中でAlt+Enterキーで改行したフレーズを書いた時です。
これって、画面上では改行コードが見えないのですが、Chr(10)が含まれます。

そんな時、置換コマンドでも出来るんですが、検索に貼る文字画面が一行だけ。
入力しながらCtrl+Jキーを押すと改行できるけど、文字が見えなくなりました。

特にカナや漢字へ変換が必要な時に、隠れた字句が変換できたのか分からない。
ならば、該当する字句にセルを当てて、置換を呼び出して改行するとします。

やってみたんだけど、改行が二つ以上になると、かなりやりづらいんだよなあ。
つまり、セル内で改行してある文言が素早く置換できたら迅速に仕上がるんだ。

    
なら、VBAでプログラムを作ってみるしかないと思って、挑戦してみましたよ。
何とかできましたが、プログラミングのミソは、配列のアイデアを活用した点。

セル内の、改行コードのChr(10)で区切られる字句を要素の配列に見立てます。
この配列内容が、指定した範囲内で各セルの内容と合致しているか確認します。

もし合致していれば、置換で指定した字区を、該当セルに書き込んで行きます。
そして、置換で指定された字句は一行から四行までに対応するようにしました。

まあ、コードの特長では、ループ処理と条件分岐式(複数)を活用した分けよ。
ループ処理のFor~Nextに、For Each~Nextを使い、他には条件分岐(複数)。

Select Caseですが、置換の字句も改行コードから要素の配列に分解しています。
それから、この要素数で判断し、改行コードを含む字句に再構成して書き込む。

このため、置換されたセルは、元の字句が三行でも、置換で四行にもできます。
まあ、セル一つで改行コードで四行以上にする人もいないと思って止めました。

というわけで、画面を操作するイベントプロシージャまで組み込んでみました。
他に開いたブックのシート画面から、置換したいセルをコピーしておき、貼り付けるセルをダブルクリックしてデータのみを張り付けるアイデアで、書式までコピペしてしまうのを防いでいるのですが、この他、セルを置換する対象になるブックと、このプログラムのブック以上にブックが開かれていると、置換が実行されないなど、それなりに実用性を意識して作ったのでした。
   
★参考までにコード記述:
※ThisWorkbookのコーディング
Private Sub Workbook_Open()

    With Application
        .WindowState = xlNormal   '標準
        .Width = 200
        .Height = 200
    End With
 
'枠線を残す・消す
    ActiveWindow.DisplayGridlines = False 'True
'行列番号を残す・消す
    ActiveWindow.DisplayHeadings = False 'True
'シート見出しの表示 / 非表示
    ActiveWindow.DisplayWorkbookTabs = False 'True
'スクロールバーを残す・消す
    ActiveWindow.DisplayHorizontalScrollBar = False
    ActiveWindow.DisplayVerticalScrollBar = False
 
Cells(3, 2).Value = ""
Cells(3, 4).Value = ""
ActiveCell = Cells(1, 1)
Worksheets(1).Activate

End Sub
-------------------------------------------------------------------------
Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal

Target As Range, Cancel As Boolean)
    On Error Resume Next
    If Not Target.Value = "" Then GoTo EndTsk
    If Target.Value = "" Then Target.PasteSpecial xlPasteValues
    Application.CutCopyMode = True
EndTsk:

End Sub
--------------------------------------------------------------------------
※モジュール1のコーディング
Sub Button1_Click()

 Dim Orgnl As Variant
 Dim Trgt As Variant
 Dim Rvsd As Variant
 Dim Cll As Range
 Dim i As Long
 Dim tmp As String

 For i = 1 To Workbooks.Count
  If Workbooks.Count > 2 Then GoTo Finish
  If Not ActiveWorkbook.Name = Workbooks(i).Name Then tmp =

Workbooks(i).Name
 Next i

Orgnl = Split(ActiveSheet.Cells(3, 2).Value, Chr(10))
Rvsd = Split(ActiveSheet.Cells(3, 4).Value, Chr(10))

Workbooks(tmp).Activate

For Each Cll In Range("A1:AQ1000")

If Cll.Value = "" Then GoTo TskEnd

Trgt = Split(Cll.Value, Chr(10))

If Not UBound(Orgnl) = UBound(Trgt) Then GoTo TskEnd

For i = 0 To UBound(Trgt)
If Not Orgnl(i) = Trgt(i) Then GoTo TskEnd
Next i

Select Case UBound(Rvsd)
Case 0
Cll.Value = Rvsd(0)
Case 1
Cll.Value = Rvsd(0) & Chr(10) & Rvsd(1)
Case 2
Cll.Value = Rvsd(0) & Chr(10) & Rvsd(1) & Chr(10) & Rvsd(2)
Case 3
Cll.Value = Rvsd(0) & Chr(10) & Rvsd(1) & Chr(10) & Rvsd(2) & Chr(10) &

Rvsd(3)
End Select

TskEnd:

Next Cll

Finish:

ThisWorkbook.Activate
Cells(3, 2).Value = ""
Cells(3, 4).Value = ""

End Sub



いいねと思ったら、三つポチっとね!
にほんブログ村 スキースノボーブログへにほんブログ村 スキースノボーブログ スキーへにほんブログ村 旅行ブログ 旅日記・旅の思い出へ
にほんブログ村    にほんブログ村      にほんブログ村 



2019年6月7日金曜日

日本だと、横浜、神戸、長崎に三大中華街があるのですが、その土地に親しんだ雰囲気を味わうなら、神戸の中華街がお勧めだと思います - 神戸南京町(神戸市・中央区)

神戸南京町長安門

正直、横浜市民であっても、わざわざ中華街へ出かけることもなくなりました。
いつの頃からかは覚えていませんが、上さんと結婚した年あたりだったかなあ。

だから、十数年以上が経っているはずで、今や中華料理は日本の料理の一分野。
日本人の口に馴染んだ料理になってしまって、中華街で食べる必要も無いよね。

なので、酢豚など日本で命名した料理で、ありえないトマトケチャップを使う。
パイナップルまで入ったりして、中国人にも想定外の料理なのかもしれません。

餃子だと、中国ではゆでるもので焼かないし、拉麺(ラーメン)は日本生まれ。
回鍋肉(ホイコーロウ)、マーボー豆腐もそうで、本場からかけ離れています。

まあ、自分の身近にある中華街は、月並みに地盤沈下して観光地の一つぐらい。
だから、興味の対象ですらなくなってしまったけれど、神戸の中華街は違った。

横浜に比べると、街区自体が小さくて、ローカル感が漂うほど異国情緒がある。
神戸の街に移り住んだ華僑が、この南京町で連綿と商売を続けている雰囲気だ。

  
横浜の方はと言うと、商店街が、どんどん新しく豪華な建物に代って行きます。
代替わりで経営者も代って、新陳代謝の激しい活気ある町だとうは思うのです。

でも、そんな賑やかで派手な町並みより、生活感のある商店街の方が良いんだ。
代々、華僑が、自分達の生業をしながら暮らし続けている雰囲気が、心地よい。

今回の大阪旅行では、ちょっと神戸まで足を伸ばしてみましたが生憎の雨です。
そんな天気ですら、観光客はことのほか多くて、傘を指し列をなして歩きます。

とぼとぼ歩いて、北京ダックを買い食いしたり、湯葉入りの肉まんを食べたり。
ちょっと、小腹が空いたら小銭を払って買い食いしつつ、通りをぶらつくんだ。

レストランの店先には、買い食いできる露店の出店がたくさん並んでいるのよ。
傘を差した立ち食いなのですが、店の軒先を借りると注意されたりしましたな。

ある意味では、面白い体験にもなったし、続けて中華食材の店も立ち寄ります。
上さんが色々物色していましたが、豆腐を干した豆干(トウガン)も安いんだ。

まあ、雨がひどくなれば、横に並んで走る元町のアーケード街に逃げればいい。
そう思いつつ、ブラブラした分けですが、ふと思い出したのは別の中華街です。

それは、世界一小さなチャイナタウンを、キューバのハバナで見たときのこと。
当時、海外営業をしており、売り込みもあり専門商社の人と出張いたしました。

商談もありますが、途中、ハバナ旧市街とその要塞群を案内してくれたりする。
後にユネスコ世界遺産に登録されましたが、宗主国スペイン時代の名残なんだ。

GSで見たクラシックカー
ハバナのチャイナタウン

街中には、革命以前に使われていたクラシックカーが走ったり、異国情緒満載。
タイムスリップした感覚でしたが、その時、ここが中華街と教えてくれました。

通りの入り口から奥に向かって、赤い中華灯篭が吊り下げられ、確かに中華街。
車窓からちら見した程度でしたが、通りの距離が50メーターと説明されます。

世界一小さいのだと言っていましたが、ネットは別の場所も紹介していました。
それは、カナダでブリテイッシュ・コロンビア州のビクトリアにあるらしい。

現在、世界最大の中華街はバンクーバーにあるのですが、両方がカナダなのか。
最近では、中華系移民も増えすぎで、カナダ政府も締め出すようになりました。

だって、移民と同時にマフィアやら犯罪まで持ち込まれたんじゃ、たまらない。
昔の華僑と違って、中共の赤化人種は、金に物言わせてモラルも低そうだしね。

というわけで、少し脱線してしまいましたが、神戸の中華街は一見の価値あり。
この後、市内を循環する観光バスに乗って、北野異人街の風見鶏の居宅を三十年ぶりに見に行ったりしまして、横浜とは一味も二味も違う貿易都市の観光を楽しんだのでした。



いいねと思ったら、三つポチっとね!
にほんブログ村 スキースノボーブログへにほんブログ村 スキースノボーブログ スキーへにほんブログ村 旅行ブログ 旅日記・旅の思い出へ
にほんブログ村    にほんブログ村      にほんブログ村 



2019年6月4日火曜日

北海道の米って、昔は猫も食べないから「猫またぎ米」とか、北海道の地名にかけて「厄介どう米」などと、ありがたくない名前だったのよ - カリフォルニアローズ米(業務スーパー笠間店・横浜市)

   
我が家では、食材の買出しが、歩ける範囲にある業務スーパーがルーチンです。
マイカーを止めてからは、買い出したものを大きなデイバッグに詰め込むんだ。

よっこらしょと背に負って歩いて帰るわけですが、お米を買うと重くなります。
夫婦だから、一月でそんなに食べないけど、5キロパックでもズシリと来るの。

ただ、業務スーパーと近場のスーパーで特売される価格の差がなくなりました。
まあ、そんな時はスーパーで買ったりしますが、ここにしかない米もあるんだ。

それがカリフォルニアローズと言うお米で、アメリカ産のジャポニカ種です。
これまでは10キロ入りの袋の販売でしたが、最近5キロが売り出されました。

10キロは重すぎで持ち帰るのも難儀ですが、5キロ袋は背にして帰られます。
なので、このお米を買おうと言ったんだけど、上さんが上手くないと言い張る。

でも、自分はこれが五つ星の”ななつぼし”の親戚みたい品種と知っていました。
実際、カリフォルニアでコメの種籾を農林試験場の職員が持ち帰ったのですな。

研修による出張の旅先だったそうですが、この米は移住した日本人が育てた米。
それで実際に持ち帰ったのは、国府田さんが生産に成功した国寶ローズなんだ。

国府田敬三郎

日本のお米ジャポニカ種は短粒米ですが、このローズは中粒米で少し長めです。
多分、現地の陸稲栽培に適した長粒種、インディカとの掛け合わせでしょうか。

なので短粒種よりパサパサしやすいと思いましたが、食べて差が分かりません。
それだけ、カリフォルニアの気候に適合した上手な品種改良だったのでしょう。

5キロで千二百円と言う安さにもびっくりしましたが、たまに食してもいいな。
我が家で食べるお米の価格レンジは、5キロで二千円以内が多いのも事実です。

この辺りだと、あきたこまち、きらら397、はえぬき、ぐらいかと思います。
北海道、秋田、山形のお米ですが、これらに比べてモチモチ感が少ないかもな。

ネットを見ると、安さに負けて買ったが、まずくて二度と買わないという人も。
カルローズと言っていましたが、国寶ローズよりグレードが低いとありました。

北緯44度北限の”ななつぼし”

でも、食べてみて差が感じられず、遜色が無いような気がしたんだけどなあ。
ただ、上さんが雑穀を加えて炊いたりしたから、味が分からなかったのかも。

というわけで、最近では、オーストラリア産米も業務スーパーで買えるのです。
コシヒカリの”開拓の稔り”と言いますが、5キロで若干お高く1、450円になり、大規模生産のためか、白く濁った白濁米も入っているとかで、やはり日本のお米と比べると品質的には劣るようですが、たまには世界のお米事情に興味を持って食べてみても良いではと思ったのでした。



いいねと思ったら、三つポチっとね!
にほんブログ村 スキースノボーブログへにほんブログ村 スキースノボーブログ スキーへにほんブログ村 旅行ブログ 旅日記・旅の思い出へ
にほんブログ村    にほんブログ村      にほんブログ村