[[20120413102254]] 『ユーザーフォームからの転記がうまくいきません2』(peridot) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『ユーザーフォームからの転記がうまくいきません2』(peridot)

[[20120411160743]]

 の続きです。

 データシート「箱サンプル」に「単価マスタ」から必要項目を抜き出し、ユーザーフォームに表示して
 ユーザーフォームの内容を「箱サンプル」シートに転記するコードを作っています。

 ★「箱サンプル」シートレイアウト

   A   B   C   D  E   F   G  H  I  J   K   L
 1 作業簿_SK            日付      合計
 2 記号 媒体名 件数    記号 媒体名 件数     記号 媒体名 件数
 3 SK1  HY   82      SK2  KZ   2       SK  KZ   2
 4 SK1  FR   11      SK2  HY   4       SK  HY   86
 5                              SK  FR   11
  :
 19 
 20
 21 作業簿_KK
 22 記号 媒体名 件数    記号 媒体名 件数     記号 媒体名 件数
 23 VA1  KK   1516    VA2  KK   224      VA  KK   1740
 24 VE1  KK   9     VE2  KK   4       VE  KK   13
  :
 35 
 36
 37 作業簿_その他
 38 記号 媒体名 件数    記号 媒体名 件数     記号 媒体名 件数
 39 VS1  10P   6192    VS2  10P   672      VS  10P   7872
 40 VS3  10P   1008                   
  :
 49

 ★「単価マスタ」シートレイアウト
   A   B    C    D    E   F    G    H    I    J
 1 単価表 
 2    記号  媒体名 基本単価 追加分 付帯業務 区分 基本コスト 単価   分類
 3    SK    KZ   19    1    1.2  1.5  22.7    17.0 作業簿_SK
 4    SK    MZ   19    1    1.2  1.5  22.7    17.0 作業簿_SK
 5    SK    HY   19    2    0   1.5  22.5    16.9 作業簿_SK
 6    SK    FR   19    0    0   1.5  20.5    15.4 作業簿_SK
  :
 17    SK    N7   19    2    1.2  1.5  23.7    17.8 作業簿_SK
 18    VO    10P   19    1    12.2  1.5  33.7    25.3 作業簿_KK
 19    VR    10P   19    0    12.2  1.5  32.7    24.5 作業簿_KK
 20    VA    KK   19    2    1.2  1.5  23.7    17.8 作業簿_KK
  :
 28    VG    KK   19    0    0   1.5  20.5    15.4 作業簿_KK
 29    Sm    N7    19    1     0   1.5  21.5    16.1 作業簿_その他
 30    Sノ    NS   19    1    0   1.5  21.5    16.1 作業簿_その他
  :
 35    VT    L7   19    0    0   1.5  20.5    15.4 作業簿_その他

 現在考えているユーザーフォームのレイアウト
 ※頭がtxtはテキストボックス、lblはラベル、cbxはコンボボックス

 txt_Date 日付
 cbx_Cls  分類
 cbx_No  枝番

 lblCode_1〜18  記号
 cbxMedia_1〜18 媒体名
 txtQty_1〜18  件数

 CommandButton1 入力(「箱サンプル」シートへの転記)
 CommandButton2 クリア(ユーザーフォームの内容をクリア)
 CommandButton3 閉じる(ユーザーフォームを閉じる)

 ・「作業簿_SK」のデータは3〜19行に入力
 ・「作業簿_KK」のデータは23〜35行に入力
 ・「作業簿_その他」のデータは39〜49行に入力
 ・枝番(SK1の"1"の部分)が奇数のものはA〜C列に、偶数のものはE〜G列に入力
 ・J〜K列には「記号&媒体名」が一致するものの件数の合計を出す

 ★ユーザーフォームの入力手順

 1.日付を入力
 2.「分類」を選択(単価マスタより)
 3.「枝番」を選択(現在1〜4)
 4.ラベル(lblCode_1〜18)に、単価マスタを参照して「分類」に対応する「記号」が全て表示される
 (「SK」が17個あれば17個表示される)
 5.コンボボックス(cbxMedia_1〜18)のリストに、それに対応した「媒体名」がセットされる
 6.テキストボックス(txtQty_1〜18)に件数を入力
 7.コマンドボタン1を押すと、件数が入力されたものの「記号+枝番」「媒体名」「件数」が「箱サンプル」シートに転記される
 8.A〜G列の内容を参照してJ〜K列に同じ「記号&媒体」の組合せの合計件数が表示される

 前トピで(Bun)様からコントロールを300個配置する案とコードをご提示いただいたのですが、
 コントロールが多すぎると入力者が混乱する恐れがあるので上のコードでも何とかできないかと考えています。

 Excel2007です。

 それでは、引き続き、私も検討していく。
 で、提案なんだけど、Bunさんがリコメンドしておられる構成と、(peridot) さんが考えている構成、
 いずれがいいかということは、たぶん「優劣」の問題ではなく、実際にこれを使う現場の人が、このマクロを使用する局面以外の
 その業務運用の流れも含めて、どちらがマッチしているかを判断することなんだろうと思う。

 なので、私は(peridot)さんがイメージしている構成を実現するコードを書く、最終的に、それを
 現場の人に判断してもらうということにすればいかが?

 Bunさんの構成では、フォームを作るのが大変だと感じるかもしれないけど、たぶん、それは1時間ぐらいで
 充分にできる作業だと思うし、もし、大変だということなら、この板でも回答されるichinoseさんが
http://www.vbalab.net/vbaqa/c-board.cgi?cmd=ntr;tree=71765;id=excel
 ここで、(peridot)さんにかわってフォームを作成する手法を提示されているので、それを利用する方法もある。
 (実際に、こちらで、(peridot)さんが説明するデザインのフォームを作る時には、ある程度までこの手法で 作成した)
 これで、作成してしまえば、それは、手作業で作成したものとなんらかわらないので、あとは 手作業で
 追加・修正等、なんでもできる。

 (ぶらっと)


 今思いついたのだけれど?
 現状のUserFormでは、横計を表示させる為、txtCodeJ、xtMediaK、txtQtyLの3組*18個のコントロールを
 使っていますが、横計を表示を行わないで転記だけにすれば、3組*18個のコントロールは削除出来ますが?
 もううんざりなら、私は降りますが、必要ならUpします如何しますか?

 (Bun)


 >ぶらっと様ありがとうございます。

 >最終的に、それを
 >現場の人に判断してもらうということにすればいかが?
 はい、お願いいたします。

 >Bun様

 横計は一度には行わず、転記した後合計(別に「合計」用のコードを用意して、それを実行した時に合計するなど)
 というように考えています。
 まずはデータ入力を行ってから、集計という手順になっていますので…
 (今は関数なので入力の都度合計も更新されますが、ワークシート上に「合計」を実行するボタンを置いて
 そのタイミングで合計しても問題ないので)

 なので3組*18個のコントロールを削除する方向でお願いできますでしょうか。

 (peridot)

 txtCodeJ、xtMediaK、txtQtyLの3組*18個のコントロールは無しにして下さい
 尚、前にも記述しましたが?
 txtCode、txtMediaの列は、LockedプロパティをTrueに、TabStopプロパティをFalseにし
 BackColorを変更して下さい

 また、CommandButton1:入力/更新、CommandButton2:入力範囲クリア、CommandButton3:閉じる、に成ります

 Option Explicit

 Private Const clngExtr As Long = 3 '抽出列数

 Private wksMark As Worksheet '入力先のシート
 Private rngList As Range    '単価マスタのデータ範囲
 Private rngWork As Range    '作業用シートの抽出範囲
 Private rngCrit As Range    '作業用シートの条件範囲先頭セル位置
 Private lngRow As Long      '抽出行数(最終行位置)
 Private rngAdd As Range     '入力範囲先頭位置

 Private Sub UserForm_Initialize()

    Dim i As Long
    Dim vntData As Variant
    Dim lngRows As Long

    '入力先のシートを指定
    Set wksMark = Worksheets("箱サンプル")

    '単価マスタ先頭セル位置を指定
    Set rngList = Worksheets("単価マスタ").Range("B2")

    '作業用シートの抽出範囲を指定
    Set rngWork = Worksheets("抽出").Range("A1")

    '作業用シートの条件範囲先頭セル位置を指定
    Set rngCrit = rngWork.Parent.Range("F1")

    'Listの行数、列数取得
    With rngList
        'B列で行数の取得
        lngRows = .Offset(Rows.Count - .Row).End(xlUp).Row - .Row
    End With

    '単価マスタのデータ範囲の再設定
    Set rngList = rngList.Resize(lngRows + 1, 9)

    'ComboBox1に「分類」を設定(各分類の先頭位置とデータ行数も其々別の列に設定)
    With cbxClass
        For i = 0 To 2
            .AddItem Choose(i + 1, "作業簿_SK", "作業簿_KK", "作業簿_その他")
            .List(i, 1) = Choose(i + 1, 2, 22, 38)
            .List(i, 2) = Choose(i + 1, 18, 14, 11)
        Next i
    End With

    '枝番の番号設定
    For i = 1 To 18
        Controls("cbxNum" & i).List = Array("1", "3")
    Next i

    '日付の読み込み
    txtDate.Text = wksMark.Cells(1, "F").Value
    If txtDate.Text = "" Then
        txtDate.Text = Date
    End If

 End Sub

 Private Sub UserForm_Terminate()

    '日付の書き込み
    wksMark.Cells(1, "F").Value = txtDate

    Set rngList = Nothing
    Set rngWork = Nothing
    Set rngCrit = Nothing
    Set wksMark = Nothing
    Set rngAdd = Nothing

 End Sub

 Private Sub cbxClass_Change()

    Dim i As Long
    Dim vntData As Variant
    Dim vntRows As Variant

    If cbxClass.ListIndex = -1 Then
        Exit Sub
    End If

    '「記号」のデータを取得
    vntData = GetComboList(cbxClass.Text, 1)

    For i = 1 To 18
        With Controls("cbxCode" & i)
            '抽出行数が0で無いなら
            If lngRow > 0 Then
                'ComboBox2にListを設定
                .List = vntData
            Else
                'ComboBox2をクリア
                .Clear
            End If
        End With
    Next i

    '出力範囲のデータを取得
    With cbxClass
        vntData = .List(.ListIndex, 1)
        vntRows = .List(.ListIndex, 2)
    End With

    '出力範囲先頭を設定
    Set rngAdd = wksMark.Cells(vntData, "A")

    '入力用コントロールの入力範囲分を表示にし、データを読み込み
    For i = 1 To vntRows
        ControlsVisible i, True
        GetLineData i, rngAdd
    Next i
    '入力用コントロールの入力範囲範囲外を非表示に
    For i = vntRows + 1 To 18
        ControlsVisible i, False
    Next i

 End Sub

 Private Sub CommandButton1_Click()

    Dim i As Long
    Dim vntRows As Variant

    With cbxClass
        If .ListIndex = -1 Then
            Exit Sub
        End If
        vntRows = .List(.ListIndex, 2)
    End With

    If MsgBox("データの更新をします!!", vbInformation + vbOKCancel) = vbCancel Then
        Exit Sub
    End If

    'データの書き込み
    For i = 1 To vntRows
        PutLineData i, rngAdd
    Next i

 End Sub

 Private Sub CommandButton2_Click()

    Dim i As Long
    Dim vntData As Variant

    If MsgBox("シートをクリアします!!", vbInformation + vbOKCancel) = vbCancel Then
        Exit Sub
    End If

    vntData = cbxClass.List

    For i = 0 To UBound(vntData, 1)
        wksMark.Cells(vntData(i, 1), "A").Offset(1).Resize(vntData(i, 2), 12).ClearContents
    Next i

    If cbxClass.ListIndex = -1 Then
        Exit Sub
    End If

    '出力範囲先頭を設定
    Set rngAdd = wksMark.Cells(vntData(cbxClass.ListIndex, 1), "A")

    '入力用コントロールの入力範囲分を表示にし、データを読み込み
    For i = 1 To vntData(cbxClass.ListIndex, 2)
        ControlsVisible i, True
        GetLineData i, rngAdd
    Next i
    '入力用コントロールの入力範囲範囲外を非表示に
    For i = vntData(cbxClass.ListIndex, 2) + 1 To 18
        ControlsVisible i, False
    Next i

 End Sub

 Private Sub CommandButton3_Click()

    Unload Me

 End Sub

 Private Sub ChangeSymbol(lngNumb As Long)

    Dim vntData As Variant

    If Controls("cbxCode" & lngNumb).ListIndex = -1 Then
        Exit Sub
    End If

    '「媒体名」のデータを取得
    vntData = GetComboList(Controls("cbxCode" & lngNumb).Text, 2)

    With Controls("cbxMedia" & lngNumb)
        '抽出行数が0で無いなら
        If lngRow > 0 Then
            'ComboBoxにListを設定
            .List = vntData
        Else
            'ComboBoxをクリア
            .Clear
        End If
    End With

 End Sub

 Private Sub ChangeNumbBox(lngNumb As Long)

    If Val(Controls("txtQtyG" & lngNumb).Text) > 0 Then
        Controls("txtCode" & lngNumb).Text _
                = Controls("cbxCode" & lngNumb).Text & (Val(Controls("cbxNum" & lngNumb).Text) + 1)
        Controls("txtMedia" & lngNumb).Text = Controls("cbxMedia" & lngNumb).Text
    Else
        Controls("txtCode" & lngNumb).Text = ""
        Controls("txtMedia" & lngNumb).Text = ""
    End If

 End Sub

 Private Sub GetLineData(lngNumb As Long, rngTop As Range)

    Dim vntData As Variant
    Dim vntTmp As Variant

    vntData = rngTop.Offset(lngNumb).Resize(, 12).Value

    'A列がEmpty値で無いなら
    If Not IsEmpty(vntData(1, 1)) Then 'A列
        vntTmp = vntData(1, 1)
    'E列がEmpty値で無いなら
    ElseIf Not IsEmpty(vntData(1, 5)) Then
        vntTmp = vntData(1, 5)
    End If
    If Not IsEmpty(vntTmp) Then
        Controls("cbxCode" & lngNumb).Text = Left(vntTmp, Len(vntTmp) - 1)
        vntTmp = Val(Right(vntTmp, 1))
        If vntTmp Mod 2 = 0 Then
            vntTmp = vntTmp - 1
        End If
        Controls("cbxNum" & lngNumb).Text = CStr(vntTmp)
    Else
        Controls("cbxCode" & lngNumb).Text = ""
        Controls("cbxNum" & lngNumb).ListIndex = -1
    End If
    If Not IsEmpty(vntData(1, 2)) Then 'B列
        vntTmp = vntData(1, 2)
    ElseIf Not IsEmpty(vntData(1, 6)) Then
        vntTmp = vntData(1, 6)
    End If
    Controls("cbxMedia" & lngNumb).Text = vntTmp
    Controls("txtQtyC" & lngNumb).Text = vntData(1, 3) 'C列

    Controls("txtCode" & lngNumb).Text = vntData(1, 5) 'E列
    Controls("txtMedia" & lngNumb).Text = vntData(1, 6) 'F列
    Controls("txtQtyG" & lngNumb).Text = vntData(1, 7) 'G列

 End Sub

 Private Sub PutLineData(lngNumb As Long, rngTop As Range)

    Dim vntData As Variant
    Dim vntTmp As Variant

    ReDim vntData(1 To 12)

    'C列の値が有ったなら
    If Val(Controls("txtQtyC" & lngNumb).Text) > 0 Then
        vntData(1) = Controls("cbxCode" & lngNumb).Text _
                        & Controls("cbxNum" & lngNumb).Text 'A列
        vntData(2) = Controls("cbxMedia" & lngNumb).Text     'B列
        vntData(3) = Controls("txtQtyC" & lngNumb).Text    'C列
    End If

    'G列の値が有ったなら
    If Val(Controls("txtQtyG" & lngNumb).Text) > 0 Then
        vntData(5) = Controls("txtCode" & lngNumb).Text  'E列
        vntData(6) = Controls("txtMedia" & lngNumb).Text  'F列
        vntData(7) = Controls("txtQtyG" & lngNumb).Text  'G列
    End If

    vntData(10) = Controls("cbxCode" & lngNumb).Text   'J列
    vntData(11) = Controls("cbxMedia" & lngNumb).Text  'K列
    vntTmp = Val(Controls("txtQtyC" & lngNumb).Text) + Val(Controls("txtQtyG" & lngNumb).Text)
    If vntTmp = 0 Then
        vntTmp = Empty
    End If
    vntData(12) = vntTmp  'J列

    rngTop.Offset(lngNumb).Resize(, 12).Value = vntData

 End Sub

 Private Sub ControlsVisible(lngNumb As Long, blnVisible As Boolean)

    Controls("cbxCode" & lngNumb).Visible = blnVisible 'A列
    Controls("cbxNum" & lngNumb).Visible = blnVisible
    Controls("cbxMedia" & lngNumb).Visible = blnVisible 'B列
    Controls("txtQtyC" & lngNumb).Visible = blnVisible 'C列

    Controls("txtCode" & lngNumb).Visible = blnVisible 'E列
    Controls("txtMedia" & lngNumb).Visible = blnVisible 'F列
    Controls("txtQtyG" & lngNumb).Visible = blnVisible 'G列

 End Sub

 Private Function GetComboList(vntCrit As Variant, lngNum As Long) As Variant

    Dim vntData As Variant

    '条件範囲にComboBoxの値を代入(式の形で)
    rngCrit.Offset(1, lngNum - 1).Value = "=""" & vntCrit & """"

    'AdvancedFilterを実行
    DoFilter rngList, rngCrit.Resize(2, lngNum), rngWork.Resize(, clngExtr)

    '抽出範囲から
    With rngWork
        '抽出行数を取得
        lngRow = .Offset(Rows.Count - .Row).End(xlUp).Row - .Row
        '列見出し以上の行が在るなら
        If lngRow > 0 Then
            '指定列からデータを配列に取得
            vntData = .Offset(1, lngNum).Resize(lngRow, 2).Value
            ReDim Preserve vntData(1 To lngRow, 1 To 1)
            GetComboList = Unique(vntData)
        End If
    End With

 End Function

 Private Sub DoFilter(rngScope As Range, _
                    rngCriteria As Range, _
                    rngCopyTo As Range, _
                    Optional blnUnique As Boolean)

  '  AdvancedFilterを実行

    rngScope.AdvancedFilter _
            Action:=xlFilterCopy, _
            CriteriaRange:=rngCriteria, _
            CopyToRange:=rngCopyTo, _
            Unique:=blnUnique

 End Sub

 Private Function Unique(vntData As Variant) As Variant

 '  値の重複取り

    Dim i As Long
    Dim j As Long
    Dim lngEnd As Long
    Dim vntList As Variant

    ReDim vntList(1 To UBound(vntData, 1))

    '値の重複取り
    For i = 1 To UBound(vntData, 1)
        For j = 1 To lngEnd
            If vntData(i, 1) = vntList(j) Then
                Exit For
            End If
        Next j
        If j > lngEnd Then
            If Not IsEmpty(vntData(i, 1)) Then
                lngEnd = j
                vntList(lngEnd) = vntData(i, 1)
            End If
        End If
    Next i

    ReDim Preserve vntList(1 To lngEnd)

    '戻り値として重複無しの値を返す
    Unique = vntList

 End Function

 ’以下のコードは3〜17分のプロシージャが間引いて有りますので補間して下さい

 Private Sub cbxCode1_Change()
    ChangeSymbol 1
 End Sub

 Private Sub cbxCode2_Change()
    ChangeSymbol 2
 End Sub
	・
	・
 Private Sub cbxCode18_Change()
    ChangeSymbol 18
 End Sub

 Private Sub txtQtyG1_Change()
    ChangeNumbBox 1
 End Sub

 Private Sub txtQtyG2_Change()
    ChangeNumbBox 2
 End Sub
	・
	・
 Private Sub txtQtyG18_Change()
    ChangeNumbBox 18
 End Sub

 (Bun)


 (Bun)様ありがとうございます。

 ユーザーフォームを作成してコードを入力して試したのですが、操作性の点でいくつか変更したい部分がありまして…

 ・現在、「分類」を選んだ後「記号」「枝番」の順に入力していきますが…
  @特に「SK」の場合「記号」は「SK」で統一なので、全部一つ一つ選ぶのはやはり手間がかかります。
   最初からコンボボックスに表示しておくのならまだよいのですが…
  A「枝番」は一度に一つの枝番しか入力しないので、これも選ぶのは一度だけにしたいです。
  Bあと、「枝番」が1と3しか表示されないのですが、2や4はどうやって入力するのでしょうか?
 ・BackColorを変えたtxtCodeC1〜18、txtMedia1〜18、txtQtyG1〜18は今何も表示されませんが、どのように使うのでしょうか?
 ・コマンドボタン2については私の説明不足でした…
 これは「ユーザーフォームの内容をクリア」したいボタンなので、こちらで下記のようにコードを書き換えました

 Private Sub CommandButton2_Click()

 Dim myCtrl As Control

    For Each myCtrl In Me.Controls
        If TypeName(myCtrl) = "TextBox" Or TypeName(myCtrl) = "ComboBox" Then _
            myCtrl.Value = vbNullString
    Next

 End Sub

 特に「記号」「枝番」の入力の部分は選択の回数が少なくて済むように変えたいです…

 (peridot)

 多分、UserFormの使い方と言うか、シートの入力の考え方が全く違う様ですね?
 文面からするとperidotさんが考えているのは、このUserFormに入力してボタンを押すと
 既に入力されている、または何も入力されていない行に上から追加されて行く様な考え方なのかと思います

 >・現在、「分類」を選んだ後「記号」「枝番」の順に入力していきますが…
 > @特に「SK」の場合「記号」は「SK」で統一なので、全部一つ一つ選ぶのはやはり手間がかかります。
 >  最初からコンボボックスに表示しておくのならまだよいのですが…

 私の作った物は、分類「作業簿_SK」で全入力範囲で18行なので、「作業簿_SK」が選択されれば
 「作業簿_SK」の入力範囲の全ての行をコントロールに読み込んでいます
 詰まり、「作業簿_SK」の範囲にデータが無ければ当然、コントロールは全て空白です
 またデータで既に入力されているなら其れが読み込まれます
 此れに因り、データの追加入力、変更を可能にしています
 因って、例えば「分類」で「作業簿_KK」を選択した時に、cbxCodeの値を先に入れて置く様にすると
 「VA」や「VE」がが既に入力(表上)に有った場合、置き換えられてしまいますので行っていません

 > A「枝番」は一度に一つの枝番しか入力しないので、これも選ぶのは一度だけにしたいです。
 > Bあと、「枝番」が1と3しか表示されないのですが、2や4はどうやって入力するのでしょうか?
 >・BackColorを変えたtxtCodeC1〜18、txtMedia1〜18、txtQtyG1〜18は今何も表示されませんが、どのように使うのでしょうか?

 txtQtyG1〜18は入力させますので(txtQtyGは右側E、F、G列のG列の件数入力用)LockedやTabStopのプロパティ
 設定はしませんよ(前回からプロパティ指定のコントロールには入れて無い筈です)
 「枝番」の入力は左側の欄(A、B、C列)は、前回迄の説明で必ず奇数番が入りまし、右側(E、F、G列)は、
 偶数番しか入らない筈だと思っています
 因って、枝番のComboBoxでは奇数番しか用意していません、最初のコードをUpした時から書いていますが?
 例えば、枝番cbxNumで1を選択した場合、C列件数xtQtyCに0若しくは""が入った場合、A、B、C列の出力は行いません
 また、xtQtyCに0を超える数値が入った場合、A列には記号+枝番が入り、B列には媒体名cbxMediaの値が入り
 C列にはxtQtyCの値が入ります
 次に、G列件数txtQtyGに0を超える値が入った場合、E列記号txtCode、F列媒体名txtMediaに表示がされます
 この時、E列記号txtCodeは、記号cbxCode&枝番cbxNum+1(枝番で1が選択されていれば2が、枝番で3が選択されて居れば4が)が表示されます

 >・コマンドボタン2については私の説明不足でした…
 >これは「ユーザーフォームの内容をクリア」したいボタンなので、こちらで下記のようにコードを書き換えました

 これも、上記の意味ならUserFormの運用と言う意味なら不要だと思います
 何故なら、此れを行って、クリアしたコントロールに値を入力してボタンを押した場合
 全て、新規に入力した物に置き換わってしまいます(詰まり、Bookの上書保存と同様な結果に成ります)

 (Bun)


 後、入力が大変だと言っていますが?
 もしかしてComboBoxの入力やコントロールの移動をマウスだけで行っているのですか?
 UserFormのTabOderが適正に設定されていれば殆どキーボードだけで操作が出来るのですが?
 ComboBoxのList選択は↓↑キーで出来ますし、コントロールの移動はTabキー若しくはShift+Tabキーで出来ます
 因って、キーボード主体で操作した方が速いし楽かも?

 (Bun)


 >文面からするとperidotさんが考えているのは、このUserFormに入力してボタンを押すと
 >既に入力されている、または何も入力されていない行に上から追加されて行く様な考え方なのかと思います
 はい、その通りです。

 元々、何も入力されていないシートにデータを入力するためのユーザーフォームなので…
 現状では、一度入力すればよいものを何度もコンボボックスから選ぶようになっているので、それは操作が大変ですので…
 従って、
 >詰まり、「作業簿_SK」の範囲にデータが無ければ当然、コントロールは全て空白です
 これでは入力しづらくなります…
 私が想定していたものが「単価マスターに組合せがあるものがコントロールに表示される」というものだったのですが…

 >キーボード主体で操作した方が速いし楽かも?
 入力する人がほとんどマウスで操作していますので、キーボード操作前提というのはちょっと…

 >txtQtyG1〜18は入力させますので(txtQtyGは右側E、F、G列のG列の件数入力用)LockedやTabStopのプロパティ
 >設定はしませんよ(前回からプロパティ指定のコントロールには入れて無い筈です)
 これは了解いたしました。
 ただ、これも説明不足でしたが「枝番2」しか件数が入らないものがあります(枝番1の件数がない場合がある)
 その時に「1」が無いと「2」の入力ができないというのは困るんです…

 私の説明が悪かったのだと思いますが、「箱サンプル」シートは始めは空白です。
 そこにデータを入力するためのユーザーフォームを作っているので、値の更新ではなく追加になります。

 なんか色々とすみません…

 (peridot)

 説明している意味が全く理解されないようなので私は降ります

 (Bun)


 Bunさんとのやりとりは、詳しく読んでいないけど、
 >そこにデータを入力するためのユーザーフォームを作っているので、値の更新ではなく追加になります。
 これが目に入ったので。

 たとえば、箱シートに SK1  HY   82      があったとする。
 で、ユーザーフォーム上でも SK1/HY を入力しようとした。
 これをどう考えるか。エラーにするのか、上書きにするのか。
 私の構想では、SK1/HYが指定されたとき、箱シートにあれば、それを該当のTextBoxに表示。
 そこをなおして実行して上書きということを考えていた。
 たとえば箱シートに 10 とはいっていた。で、フォーム上に 10 を表示して、操作者が 12 になおすと
 箱シートの行追加ではなく、上書きで 12 にしようかなと。

 そこは、どのように考えている?

 (ぶらっと)


 「予告」

 コードアップが遅れていて申し訳なし。
 書き殴った状態で、90%ぐらいはできているんだけど、もう少し時間ください。
 で、お願い事項。

 ・↑で質問している、箱サンプルに同じ記号、媒体があったときの措置、そちらの見解を知らせてください。
 ・書き殴った状態で、さらにDictionaryが増えたり、18行のコントロールのイベント処理で、コードが大きく、また複雑になっているので
  そのすべて、あるいは一部をクラスモジュールの移そうと考えている。
  あわせて、現在のコードはユーザーフォームを表示するときに負荷がかかる構成なので、一部を  ブックを開くときの処理にもっていって
 負荷分散をしようかなと思っている。
  ★そうすると、ブックを開いた後、単価マスタを変更したり、後述するけど、箱サンプルのレイアウトを変更しても
   反映しない。それでいいと思うけど、OKかどうか確認お願い。
 ・で、その箱サンプル。
 処理対象の分類コードをコードの中で固定であたえるのではなく、箱マスタに存在するコードにする予定。
 で、勝手に以下のレイアウト規定にしている。これでOKかどうか、確認お願い。
 1)分類コードが記載されたA列の次の行には"記号"と書かれていて、その次の行からデータ行。
   そのデータ領域の最後の行の下には1行空白セルがあって、その下の行から、次の分類コードがはじまる。(これは現行通りだよね)
 2)最後の分類コードのデータ領域の終わりが見えない。なので、最後のデータ領域行の1つ下の行は空白セルで、その下の行に、何かこれで終わりだというものが欲しい。
  なんでもいいけど "END" でもいいし、"終了" でもいいし、もっと気の利いた別の語句でもいいけど。
  こういう構えにできるかどうか、確認お願い。

 追加確認依頼) ユーザーフォームはモーダル表示?モードレス表示?

 (ぶらっと)

 (Bun)様、申し訳ございませんでした

 (ぶらっと)様

 >たとえば、箱シートに SK1  HY   82      があったとする。
 >で、ユーザーフォーム上でも SK1/HY を入力しようとした。
 >これをどう考えるか。エラーにするのか、上書きにするのか。

 上書きになります。

 >書き殴った状態で、さらにDictionaryが増えたり、18行のコントロールのイベント処理で、コードが大きく、また複雑になっているので
  >そのすべて、あるいは一部をクラスモジュールの移そうと考えている。

 すみません、クラスモジュールというのが全然わかっていないのでお任せします…

 > 1)分類コードが記載されたA列の次の行には"記号"と書かれていて、その次の行からデータ行。
   そのデータ領域の最後の行の下には1行空白セルがあって、その下の行から、次の分類コードがはじまる。(これは現行通りだよね)

 はい。
 ただ、データ領域の最後の行まで必ずしもデータが入るとは限りません。
 何故なら、例えば「作業簿_SK」の中で「SK3」が発生するかどうかは日によって違い、発生した時のために
 単価マスタにある組合せよりも2行ほど余分にデータ領域を作っています。

   A   B
 1 作業簿_SK
 2 SK1  KZ
 3 SK1  MZ
   :
 17 SK1  N7  ←ここまでが単価マスタにある組合せの最大行
 18 SK3  MZ  ←もし「SK3」がある時はここに追加
 19       ←想定しているデータ行の最終行
 20
 21 作業簿_KK
 22 VO1

 「作業簿_KK」「作業簿_その他」も同様の構成になっています。

 >2)最後の分類コードのデータ領域の終わりが見えない。なので、最後のデータ領域行の1つ下の行は空白セルで、その下の行に、何かこれで終わりだというものが欲しい。

 では、誰が見ても分かるように「データ行終了」をA51(A49が「作業簿_その他」の最終行)に入れます。

 ユーザーフォームはモードレスを考えていましたが、不都合があればモーダルでも構いません。

 よろしくお願いいたします。

 (peridot)

 確認ありがとう。ほぼ、ほぼつかめた。
 クラスがよくわからないということなので、クラスそのものは「ブラックボックス」として
 後々、「中身を見ないでもすむ」ように、データ処理は、クラスから外に出して、(peridot)さんが
 見てわかるような場所、ユーザーフォームモジュールや標準モジュールに移すように、すこし組み変える。

 ただ、根本的に、そちらで想定した仕様に「矛盾点」があるような気がしてきた。

 >例えば「作業簿_SK」の中で「SK3」が発生するかどうかは日によって違い、発生した時のために
 >単価マスタにある組合せよりも2行ほど余分にデータ領域を作っています。

 つまり、アップされた例で言うと、作業簿_SK に対する単価マスタは、3行目から17行目までの15行。
 で、「余裕をみて?」18行用意したということを言っているのかな?
 たまたま、作業簿_SK の 記号は SK だけなので、ユーザーフォームの18行のラベルに全て SK をいれ
 18行分の入力を可能にしている?

 これは、ちょっと、おかしいかも。

 作業簿_SK の記号は、「たまたまSKだけ」かもしれないけど、理屈(データ構造)としては、作業簿_KK のように
 複数の記号が登録されていることもありうるよね。
 仮に、単価マスタに作業簿_SKに関して、SKが10行、SXが3行、SWが2行登録されていたとする。
 ユーザーフォームの各行のラベルは、どうなると想定している?(SKが何行、SXが何行、SWが何行??)

 準備したコードでは、この場合、あらかじめデザインされた18行のうち、上の15行だけを表示、
 下の5行は非表示にして、ラベルは上から、SKが10行、SXが3行、SWが2行 となる。
 こうせざるを得ないのは理解してくれるかな?

 なので、一度に、15行までしか入力(登録)できないので、16行以上ある場合は、2回に分けてということになる。
 要は、単価マスタに登録されている記号の数だけユーザーフォームに展開する。それが18行なら、18行をフルに
 使うことになるし、いつの日か、単価マスタが20行になった、でもユーザーフォームは18行しか用意していない。
 こういうことが発生したら、エラーメッセージを出して処理できないようにしている。

 なお、フォーム表示はモーダルでもモードレスでも、どちらでもOKにしておいた。
 (数量欄入力にエラーがあった場合のエラーメッセージ処理が、モーダルと、モードレスでは
 通常のコードでは、ちょっと結果が異なるんだけど、そこは、少し手を入れて同じ結果になるように
 対応した)

 それと、このトピも、かなり大きくなったので、編集しづらい場面がでてきている。
 No.3 を立ち上げてくれればありがたいかな。

 (ぶらっと)

 (ぶらっと)様ありがとうございます

[[20120416142118]]

 で次のトピを立ち上げましたのでよろしくお願いいたしますm(__)m

 peridot)

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.