[[20080309193831]] 『日付を参照してデータの入力をしたい』(SAPPHIA) ページの最後に飛ぶ

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

 

『日付を参照してデータの入力をしたい』(SAPPHIA)

初めまして、質問させていただきます。

現在、勤務時間を入力するのにユーザーフォームを作って実行しているのですが、
うまくマクロが組めないでいます。現状では、

 ・ユーザーフォームには、個人選択コンボボックス(個人別シートを選択)、日付選択コンボボックス、出勤時間&退勤時間入力テキストボックス、備考入力テキストボックス(遅刻・早退理由などを入力)を配置。
 ・個人別のシートのAD4〜34には日付が入力済み。
 ・ユーザーフォームの日付選択用コンボボックスには、「リスト」シートから日付データを読込み済み。
 ・現状では、日付の選択は無視され、各個人別シートの一番上の空白セル(AE4から下のデータ未入力セル)から入力される。
 ・各データは、「入力」ボタンをクリックした時点でシート内の表に入力される。

これを、各個人別のシートを選択後(アクティブにした後)、そのシート内の日付をコンボボックスで選択した日付と照らし合わせて、該当したセルに各データを入力したいのです。

いろいろ検索して、いくつか参考になるコードを試してみたのですがうまくいかず、現在手詰まりの状態です。

うまい方法があれば、教えて頂きたいと思います。エクセルのバージョンは2002と2003、OSのバージョンはWindows2000とXPです。

以上よろしくお願い致します。


 状況はなんとなくわかりますが、コードがどうなっているかわからないことには、
 改善方法の提案もできません。

 まずは試してみたコードを提示してはどうでしょうか。
 (できれば全体がいいですが、あまりに大きいようでしたら対象部分を。)
 (Mook)


 実際のコードは、もう少し詳しく
(このユーザーフォームにとって、入力データは何で出力データは何なのかを
 具体的な事例を示して提示する)記述されれば、
 ざっと投稿を拝見した限りでは回答投稿があると思います。

 が・・・・、私が疑問に感じたのはそれ以前のシート構成に関することです。

 個人別(社員ということでしょうか? その社員の人数分だけ)に出勤&退社データを入力するシートを
 作成している点です。

 VBAを使わないExcelユーザーなら、これも仕方ないと言えます。
 これというのは、たぶん、個人別にシートを作成し、それぞれのシートに出勤&退社データという個人名こそ
 違いますが、データの種類としては、全て同じ(日付、出勤時刻、退社時刻、備考、etc)ものを書き込む。

 これらのシートは、データを蓄積するテーブル兼、閲覧用レイオウト兼、印刷レイアウト兼etcに
 なっていたのではないですか?

 VBAで自動化していないなら、私もこうするかもしれんません。

 でも、VBAでExcelをデータベースに見立ててプログラミングするなら、
 この各シートのある出勤&退社データは、データを蓄積するための
 テーブルと位置づけて考えた方がよいと思いますよ!!

 そういう位置づけをすれば、シートは、せいぜい二つで済みます。

 一つは、社員マスターデータを作成するシート
 もう一つは、出勤&退社データ

 社員マスターシートには、一例ですが

 コード 社員名   住所  TEL 携帯 扶養者  ・・・

 等、今回の勤務時間を管理するのには、直接必要のないデータも項目として作成しておいても 良いです。
 これは、社員データとして、別の用途にも使用できるように項目内容を検討します。

 出勤&退社データシートは、 一例ですが

 日付  社員コード 出勤時刻  退社時刻  備考

 というような項目を作成し、個人とか日付などの枠をはずし、ここにひたすらデータを入力することを
 考えます。

 個人別のデータや一ヶ月の勤務実績の集計などはこのデータベースから必要なデータを抜粋して行うのです。

 大きいデータとしては、この二つのみです。

 このようにしておけば、社員が増えても減っても管理が楽になります。

 それとこのデータを置くブックとVBAコードを置くブックは別にすることも検討してください。

 ichinose@Qちゃん負けた


 返答が遅くなりましたが、みなさまご回答ありがとうございます。また言葉足らずで
 申し訳ありませんでした。

 実は、個人別データシートには出退勤時間以外にも、作業日や作業時間などのデータも
 格納するようになっておりまして(これは別のユーザーフォームにて入力)、各個人・
 各1枚のシートで管理するようにしておりました。

 入力したいデータを抜粋すると、

 日付|出勤(時)|出勤(分)|退勤(時)|退勤(分)|
 1日|    |    |    |    |
 2日|    |    |    |    |
 3日|    |    |    |    |
     ↑     ↑    ↑    ↑   (「↑」のセルに入力)

 ・・・といった感じです。(時)(分)はTIME関数で結合し、[○○:△△]としています。
 また、現状のVBAコードは以下になります。

 Private Sub 日付_Change()

 Dim Num As Integer

 Num = 日付.ListIndex

 If ActiveCell.Column = 8 Then
 ActiveCell = Worksheets("ユーザーフォーム用リスト").Cells(Num + 2, 1)
 End If

    MsgBox ("日付は合っていますか?確認してください"), vbExclamation

 End Sub

 以上が日付選択コンボボックスのコードで、

 Private Sub 入力ボタン_Click() '[入力!]

 作業者名 = 作業者名.Value
 日付 = 日付.Value
 出勤時 = 出勤時.Value
 出勤分 = 出勤分.Value
 退勤時 = 退勤時.Value
 退勤分 = 退勤分.Value
 備考 = 備考.Value
 定時勤務時間 = "=BA3"

    If 作業者名 = "" Or 日付 = "" Or 出勤時 = "" Or 出勤分 = "" Or 退勤時 = "" Or 退勤分 = "" Then
    MsgBox "未入力項目があります。確認してください。", vbExclamation
    Exit Sub
    End If

    Range("AC34").End(xlUp).Offset(1, 0).Select

    With ActiveCell
    .Offset(0, 1) = Val(出勤時)
    .Offset(0, 2) = Val(出勤分)
    .Offset(0, 5) = Val(退勤時)
    .Offset(0, 6) = Val(退勤分)
    .Offset(0, 9) = Val(定時勤務時間)
    .Offset(0, 17) = 備考

    End With

    出勤時 = ""
    出勤分 = ""
    退勤時 = ""
    退勤分 = ""
    備考 = ""

 End Sub

 以上が出退勤時間入力のコードとなっています。

 またichinoseさんからもご指摘がありましたが、今後はシートの扱いの見直し・
 VBAとデータを別のブックにする事も検討したいと思います。

全体的な改善はさておき、今回の件に関しては

 > ・現状では、日付の選択は無視され、各個人別シートの一番上の空白セル(AE4から
 >   下のデータ未入力セル)から入力される。

 を実行している部分は、
    Range("AC34").End(xlUp).Offset(1, 0).Select
 です。

 >そのシート内の日付をコンボボックスで選択した日付と照らし合わせて、該当したセルに
 >各データを入力したいのです。 
 のようにするには、日付を日付列と比較して、マッチした列を選択するようにする必要が
 あります。

 日付列が記載されていないので具体例は差し控えますが、Find なり For で検索して行を
 特定すればよいでしょう。
 また、指定された日付がない場合の処理等もあったほうがよいと思います。
 (Mook)

 MOOKさん、ありがとうございました。もう少しだけ教えてください。

 >日付列が記載されていないので具体例は差し控えますが、Find なり For で検索して行を
 >特定すればよいでしょう。

 これは、

 1.コンボボックスで日付を選択すると同時に、日付が入力されているセルの範囲(AC4〜AC34)を検索
 2.入力ボタンをクリックした時点で、該当セルの列へデータを入力

 といった考え方でよろしいですか?(違っていたらご指摘ください)

 また、自分なりに頭を捻ってみて、

 1.コンボボックスで日付を選択すると同時に、日付が入力されているセルの範囲(AC4〜AC34)を検索し、
  アクティブセルを該当セル(例えば、AC4)に移動
 2.入力ボタンをクリックして、該当セルの列(AD4から右)へデータを入力

 といった形でもいいのかな?と考えてみました。

 どちらにせよ、まずは実行してみないと始まらないですが、参考までに知恵を頂けたら幸いです。

 コンボボックスで日付を選択すると同時でもよいですが、それだと入力ボタンをクリックする
 まえに複数回コンボボックスを変更した場合、無駄な処理が発生しますから、クリックボタンを
 押した段階で全体の処理をすればよいと思います。

 Range("AC34").End(xlUp).Offset(1, 0).Select
 以降の代わりに、

 Dim dLine As Integer
 dLine = 0

 Dim i As Integer
 For i = 4 To 34
    If CDate(Cells(i, "AC")) = CDate(日付) Then
        dLine = i
        Exit For
    End If
 Next
 If dLine = 0 Then
    MsgBox "選択した日付[" & 日付 & "]がシートにありません"
    Exit Sub
 End If

 With Cells(dLine, "AC")
    .Offset(0, 1) = Val(出勤時)
    .Offset(0, 2) = Val(出勤分)
    .Offset(0, 5) = Val(退勤時)
    .Offset(0, 6) = Val(退勤分)
    .Offset(0, 9) = Val(定時勤務時間)
    .Offset(0, 17) = 備考
 End With
 のような感じでしょうか。

 それよりも、ユーザフォームで対象シート(ユーザ単位?)を選択しても、処理の中で
 それを使用していないほうが気になりました。
 提示されたコードでは(上記のコードも)、アクティブシートを対象としていますので、
 フォーム上でシートを選択したのが利用されていないですよね。

 Worksheet("シート名").Range("A1")
 のように指定すれば、アクティブシートにかかわらず、シートが指定されるのでトラブルが
 少ないように思います。
 これを機会にセルの指定方法に関して理解を整理してみてはどうでしょうか。

 日付の比較方法!
http://www.accessclub.jp/bbs5/0004/vba679.html
 SELECTするな!
http://officetanaka.net/excel/vba/speed/s2.htm

 (Mook)

 Mookさん、丁寧な回答ありがとうございます。

 >それよりも、ユーザフォームで対象シート(ユーザ単位?)を選択しても、処理の中で
 >それを使用していないほうが気になりました。
 仰るとおりです(汗)過去に作成したデータを基に、改良しようと試行錯誤していた事もあるかも
 知れません。

 ・・・マクロを組み始めて半年程度ですが、まだまだ修行が足りないですね。

 >これを機会にセルの指定方法に関して理解を整理してみてはどうでしょうか。
 そうですね、今までは本を片手に独学でマクロを組んできたので、今後はデータシート管理や
 セルの指定についてもっと考えてみようと思います。

 ご回答頂きましたMookさん、ichinoseさん御両名には感謝致します。また躓いたら質問させてください。

コメント返信:

[ 一覧(最新更新順) ]


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