2019年4月17日水曜日

菊池遊星もスプリットを投げるけど、自分の関心ごとはVBAのSplit関数なんだな - VBA・Split関数(そのほか)

   
マリナーズの菊池遊星投手は、待望の初勝利まで後一歩のところで届きません。
勝利投手の権利をもらって降板しても、その後逆転される不運が続いています。

三試合連続となると、もう少し長いイニングを投げさせるべきだと思うのです。
だって、中継ぎ、救援の投手陣がパッとしなくて、芳しい戦績に至らないんだ。

この菊池投手は、投げる球種を見ると直球が半分以上でスライダーが三割です。
これ以外もフォークやカーブも投げますが、スプリットは5%だけ投げるんだ。

このスプリットと言うのは、チェンジアップともいいますが、呼び名が面白い。
ボールの握りに工夫を凝らしたフォークボールの一種ですが、落ちる球のこと。

縦に割れるように落下するから、”Split”になったのでしょうが、お話はVBA。
要するに、このプログラム言語にも、”Split”というコマンドが存在しています。

実際、このコマンドをエクセルを使う仕事の中で使ってみましたが役立ちそう。
よくある使用例は、名簿の中で、セルにある氏名を苗字と名前に分けたい時ね。


苗字と名前の間は、分かりやすく空白が設けられているケースが良くあります。
この場合、このスペースを分ける条件にして氏名と苗字を別のセルに流し込む。

Sub Sample()
  
    Dim i As Long
    Dim tmp As Variant
  Dim j As Long
  
  j = Cells(Rows.Count, 1).End(xlUp).Row
  
    For i = 2 To j
   
        tmp = Split(Cells(i, 1), " ")
        Cells(i, 2) = tmp(0)
        Cells(i, 3) = tmp(1)
   
    Next i
   
End Sub

上記のようなコマンドになり、使い道は色々とあるので覚えておくと便利です。
このSplit関数は、区切り文字の条件で、要素を分割して、一次元配列にします。

コマンドでは、結果をセルに書き込んで可視化しますが、要素の配列値に注意。
tmp(0)から要素の配列が始まるのと、変数宣言したようにバリアント型なんだ。

このような約束事を守ると活用できますが、今回の応用事例は少し複雑でした。
それは、一つのセルの中に複数の作業を”→”で区切って書き込んだ要素がある。

進捗内容ですが、要素数は、セル毎にバラバラで何個あるかは分からないんだ。
プロジェクトの進捗を管理する一覧表なんですが、初めはメモ書き程度でした。

なので、セルに”→”で区切って進捗内容を書き足すうちに、要素が増えました。
こうなると、要素を見落とすかもしれず、行程を確実に把握したくなりました。


問題は、セルに要素数が何個あるかは可変だから、それを把握させるべきです。
ここで配列とはなんぞやと言うことですが、メモリ上に記憶されたデータの事。

なので、VBAの別関数”Ubound”を使って、最も大きい要素の番号を取得します。
ただ、このIDになる番号の値は、ゼロで始まるので繰り返し構文には、要注意。

For i = 0 To UBound(tmp)となりますが、別関数の”LBound(tmp)”は”0”だよ。
まあ、この手の約束事は守りつつ、各要素をユーザーフォームに書き出したい。

そして、全ての要素をテキストボックスに表示したら処理を離れる必要もある。
この判断はIf文にして、繰り返し変数が、Ubound(tmp)に達したら離れます。

ついでですが、処理分岐のために、メッセージボックスを使ったのもアイデア。
該当セルをダブルクリックしますが、いいえを選ぶとセルの入力もできるんだ。

仕事上、そういった作業が必要になったので、がんばってVBAに記述しました。
と言うわけで、試しに使ってみたいと思う人は、ご自由にコピペしてください。

会社では、ノルマで改善提案を月に何件書けといわれておるのですが、この手のVBAで書いたプログラムはうってつけでして、業務改善と称して提案シートにシコシコと書き込む自分がいるのでした。

※セルをクリックして処理の分岐・メッセージボックス利用(該当シートにコード記述)
Private Sub Worksheet_BeforeDoubleClick _
(ByVal Target As Range, Cancel As Boolean)

If MsgBox("ユーザーフォーム:はい" & vbCrLf & "セル入力:いいえ", vbYesNo) = vbYes Then
UserForm1.Show
Else
Cancel = False
End If
  
End Sub
  
※UserForm1のコード記述(フォームの初期化・テキストボックス表示・ボタン設定)
★フォームの初期化
Private Sub UserForm_Initialize()
  
Call DataShowing
  
End Sub
  
★テキストボックス表示
Private Sub DataShowing()
  
    Dim tmp As Variant
    Dim i As Long
    Dim m As Long
  
    m = ActiveCell.Row
    tmp = Split(Cells(m, 2).Value, "→")
  
If UBound(tmp) > 14 Then
    MsgBox "処理内容数があふれました。" & vbCrLf & "セルから確認してください。"
End If
   
For i = LBound(tmp) To UBound(tmp)
  
       If i = 0 Then Me.TextBox1.Text = tmp(i)
       If UBound(tmp) = i Then GoTo Finish
       If i = 1 Then Me.TextBox2.Text = tmp(i)
       If UBound(tmp) = i Then GoTo Finish
       If i = 2 Then Me.TextBox3.Text = tmp(i)
        If UBound(tmp) = i Then GoTo Finish
       If i = 3 Then Me.TextBox4.Text = tmp(i)
        If UBound(tmp) = i Then GoTo Finish
       If i = 4 Then Me.TextBox5.Text = tmp(i)
        If UBound(tmp) = i Then GoTo Finish
       If i = 5 Then Me.TextBox6.Text = tmp(i)
        If UBound(tmp) = i Then GoTo Finish
       If i = 6 Then Me.TextBox7.Text = tmp(i)
        If UBound(tmp) = i Then GoTo Finish
       If i = 7 Then Me.TextBox8.Text = tmp(i)
        If UBound(tmp) = i Then GoTo Finish
       If i = 8 Then Me.TextBox9.Text = tmp(i)
        If UBound(tmp) = i Then GoTo Finish
       If i = 9 Then Me.TextBox10.Text = tmp(i)
        If UBound(tmp) = i Then GoTo Finish
       If i = 10 Then Me.TextBox11.Text = tmp(i)
        If UBound(tmp) = i Then GoTo Finish
       If i = 11 Then Me.TextBox12.Text = tmp(i)
        If UBound(tmp) = i Then GoTo Finish
       If i = 12 Then Me.TextBox13.Text = tmp(i)
        If UBound(tmp) = i Then GoTo Finish
       If i = 13 Then Me.TextBox14.Text = tmp(i)
        If UBound(tmp) = i Then GoTo Finish
       If i = 14 Then Me.TextBox15.Text = tmp(i)
  
    Next i
   
Finish:
  
End Sub
 
★ボタン設定
Private Sub CommandButton1_Click()
Unload Me
End Sub

UserForm1
メッセージボックス



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



0 件のコメント:

コメントを投稿