なずブログ

インフラSE、Java開発、リモートワークエンジニアな人のメモ帳

ExcelVBAでユーザーフォームは使わないほうがいい

f:id:nazuna_0124:20170312082946p:plain

タイトルからディスってるようにしか見えないですが、

そんなことはありません!!


きっかけはこちらの記事様。


thom.hateblo.jp



動的フォーム!!

VBA覚えたての頃に1ヶ月かかって管理システム作ったあとに

それ使う部署ごとなくなって以来、まともに導入したことありません。



とりあえずほぼおなじものは作ってみました。

なんかこう、、、自分の見ると小学生の作文みたいで悲しくなりますが

動くのでよし。



とりあえずタイトルの使わないほうがいい理由ですが。

学習コストの割に、どうがんばって作ってもユーザーが使いにくいです



フォームを使いたい理由をもう一度よく考えて

普通にシート、HTAAccessのどれかにしときましょう。


あ、でも見た目だけ綺麗にするのには悪くないので割り切るならそれでも。



f:id:nazuna_0124:20171211123202g:plain



見た目がしょっぱいのは気にしないで!!!



コードはこちら


標準モジュール



Const MAX_BTN_CNT = 5


Sub msgTxt(ByVal contName)
    Dim frm As UserForm
    
    Set frm = UserForm1
    
    frm.TextBox1.Value = contName & "が選択されたよ!"
    

End Sub


Sub ChangeBtnCaption(ByVal page)
    Dim frm As UserForm
    
    Set frm = UserForm1
    
    Dim c As Control
    
    Dim btnList As Scripting.Dictionary
    
    Set btnList = btnNameList
    
    page = (page - 1) * MAX_BTN_CNT
    
    
    Dim i As Long
    Dim listCnt As Long
    
    
    For i = 1 To MAX_BTN_CNT
        Set c = frm.Controls("btnSelect" & i)
        
        listCnt = i + page - 1
        
        If listCnt < btnList.Count Then
        
            c.Caption = btnList.Keys(listCnt)
    
        Else
             c.Caption = "-"
        End If
    
    Next
    

End Sub

'ページ数の定義
Function maxPage() As Long
    Dim cnt
    
    cnt = btnNameList.Count \ MAX_BTN_CNT
    
    
    If btnNameList.Count Mod MAX_BTN_CNT <> 0 Then
        cnt = cnt + 1
    
    End If
    
    maxPage = cnt
 
End Function


'ここでボタン名を定義
Function btnNameList()
    Dim dic As New Scripting.Dictionary
    
    dic.Add "項目A", ""
    dic.Add "項目B", ""
    dic.Add "項目C", ""
    dic.Add "項目D", ""
    dic.Add "項目E", ""
    dic.Add "項目F", ""
    dic.Add "項目G", ""
    dic.Add "項目H", ""
    dic.Add "項目あ", ""
    dic.Add "項目い", ""
    dic.Add "項目う", ""
    dic.Add "項目え", ""
    dic.Add "項目お", ""
    dic.Add "項目サ", ""
    dic.Add "項目シ", ""
    dic.Add "項目ス", ""

    Set btnNameList = dic


End Function




フォームのとこのコード。


Private Sub btnNext_Click()
    Dim page
    

    page = Right(Me.Label1.Caption, 1)
    
    If page < maxPage Then
        page = page + 1
        
        ChangeBtnCaption page
        
        Me.Label1.Caption = "ページ" & page
    Else
        Debug.Print "last"
    
    End If
    
End Sub

Private Sub btnPre_Click()
    Dim page
    

    page = Right(Me.Label1.Caption, 1)
    
    If page > 1 Then
        page = page - 1
        
        ChangeBtnCaption page
        
        Me.Label1.Caption = "ページ" & page
    Else
        Debug.Print "first"
    
    End If
    

End Sub


Private Sub btnSelect1_Click()
    msgTxt Me.ActiveControl.Caption
End Sub

Private Sub btnSelect2_Click()
     msgTxt Me.ActiveControl.Caption
End Sub

Private Sub btnSelect3_Click()
     msgTxt Me.ActiveControl.Caption
End Sub

Private Sub btnSelect4_Click()
     msgTxt Me.ActiveControl.Caption
End Sub

Private Sub btnSelect5_Click()
     msgTxt Me.ActiveControl.Caption
End Sub



Private Sub UserForm_Initialize()
    ChangeBtnCaption 1
End Sub


btnSelect◯が5個並んでるのがかっこわるいですな!

だって、この程度の数ならコピペのほうがはやいんだもん。


そしてこれより増えるなら、Excelユーザーフォーム自体をやめたほうがいい

というおはなし。


こっそり2桁には対応してなかったりもします!



個人的によくやるのが、項目名をdictionaryにしてしまう部分。

実際に使う時はシートでユーザーに定義させることも多いのでは。


とにかくすぐ変更するとわかっている部分なのでこんなかんじ。

collectionじゃないのは、データにスタイル情報とか入れるんじゃないかなーと。



トータル作成時間は30~40分。



過去にユーザーフォームとの格闘で200時間くらいは使ったので

まったく割にあわないです。。。



ユーザーフォームを勉強したくなったタイミングが

Accessの勉強しどきです!

あわせてどーぞ!

Accessマクロ&VBA 開発工房 Office365/2019/2016/2013対応

Accessマクロ&VBA 開発工房 Office365/2019/2016/2013対応