Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


844 / 13645 ツリー ←次へ | 前へ→

【77980】再び質問 勤怠システムを自作したい 16/2/22(月) 14:34 質問[未読]
【77983】Re:再び質問 ichinose 16/2/23(火) 8:28 発言[未読]
【77984】Re:再び質問 勤怠システムを自作したい 16/2/23(火) 12:06 発言[未読]
【77985】Re:再び質問 β 16/2/23(火) 19:24 発言[未読]
【77986】Re:再び質問 β 16/2/23(火) 19:52 発言[未読]
【77987】Re:再び質問 yuto 16/2/23(火) 20:16 発言[未読]
【77991】Re:再び質問 ichinose 16/2/24(水) 6:55 発言[未読]
【77992】Re:再び質問 β 16/2/24(水) 7:36 発言[未読]
【77993】Re:再び質問 勤怠システムを自作したい 16/2/24(水) 11:53 質問[未読]
【77994】Re:再び質問 ichinose 16/2/25(木) 2:11 発言[未読]
【78000】Re:再び質問 ichinose 16/2/28(日) 15:46 発言[未読]
【77999】Re:再び質問 β 16/2/27(土) 19:59 発言[未読]

【77980】再び質問
質問  勤怠システムを自作したい  - 16/2/22(月) 14:34 -

引用なし
パスワード
   タイマーの件ありがとうございました、上級者の皆さんの言っていることがレベルが高すぎてなかなか理解が難しいですが、徐々に見た目が整ってきました。


現在までに完了しているところ、
・今日の日付の自動取得、または任意に変更可能
・コンボボックスで名前の取得、デフォルト設定済み
・操作のオプションボタン、出勤、退勤、休憩入、休憩出。デフォルト設定済み
・タイマーのリアルタイム表示
・実行ボタンの設置(テストでテキスト出力に設定してある)→最終的にオプションボタンの内容に応じてデータをセルにセットできるようにする。


次にやりことを書いてみます。
出勤時刻等のラベル貼りまで完了したので、コンボボックスで名前を選択すると、それぞれのラベルにその日に打刻したデータが表示されるプログラム。

例えばコンボボックスでAさんを選択すると、
出勤打刻されていればフォーム上のラベルのその時間をシートAさんのセルから引っ張ってきて表示する。
ここをVlookupで解決しようとしましたが訳がわからなくなってしまいました。
そもそもInitialize上で全てやろうとしているのがよくないのかも知れません。

アドバイスお願いします。


Private Sub CommandButton1_Click()
Dim sousa As String
Dim i As Integer
  For i = 1 To 4
   If Me.Controls("OptionButton" & i).Value = True Then
   sousa = Me.Controls("optionbutton" & i).Caption
  End If
  Next i
  MsgBox sousa


End Sub


Private Sub UserForm_Initialize()

OptionButton1.Value = True


  DoLoop = True
  Application.OnTime Now(), "今何時"
  
With ComboBox1
  .AddItem "A"
  .AddItem "B"
  .AddItem "C"
  .AddItem "D"
End With


  Dim i As Long
  
  'コンボボックスのドロップダウンリストの準備
  '年:例えば1900年〜現在年まで選べるようにする。
  For i = 1900 To Year(Now())
    cmb年.AddItem i
  Next i
  'デフォルト値は現在年とする。
  cmb年.ListIndex = Year(Now()) - 1900
  
  '月:1〜12
  For i = 1 To 12
    cmb月.AddItem i
  Next i
  
  'デフォルト値は現在月とする。
  cmb月.ListIndex = Month(Now()) - 1
  'ここでもcmb月_Changeイベントが発生するので,
  'そのイベント内でcmb日は年月によって準備されている。
  
  'デフォルト値は現在日とする。
  cmb日.ListIndex = Day(Now()) - 1
  
   Dim newdate As String

 '年・月・日から日付データを組み立て
 newdate = Me!cmb年 & "/" & Me!cmb月 & "/" & Me!cmb日

ComboBox1.Text = ComboBox1.List(0)


  '出勤時刻の検出'
  Dim namae As String
  namae = ComboBox1.Tex
  
  On Error GoTo ErrHdl
  With ActiveSheet
  
  If namae = "A" Then
  Label15 = _
  Application.WorksheetFunction.VLookup(newdate, Range("data"), 2, False)


  End If
  End With
  
ErrHdl:
  Label15 = ""


End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
  DoLoop = False
End Sub


Private Sub cmb月_Change()
  
  Dim 年 As Integer
  Dim 月 As Integer
  Dim 日 As Integer
  Dim 月末日 As Integer
  Dim i As Integer
  
  年 = cmb年.Value '選択されている年
  月 = cmb月.Value '選択されている(変更された)月
  日 = cmb日.ListIndex + 1 '選択されている日
  
  Select Case 月 '選ばれた月によって日数を決定する
    Case 1, 3, 5, 7, 8, 10, 12: 月末日 = 31 '大の月
    Case 4, 6, 9, 11: 月末日 = 30 '小の月
    Case 2 '2月のうるう年判定
      If 年 Mod 400 = 0 Then '西暦が400で割り切れる年はうるう年である。
        月末日 = 29
      ElseIf 年 Mod 100 = 0 Then '西暦が400で割り切れない場合、
        月末日 = 28      '100で割り切れる年はうるう年ではない。
      ElseIf 年 Mod 4 = 0 Then '西暦が100で割り切れない場合、
        月末日 = 29     '4で割り切れる年はうるう年である。
      Else
        月末日 = 28 '西暦が4で割り切れない場合、うるう年ではない。
      End If
  End Select

  With cmb日 '日のコンボボックスの処理
    .Clear 'いったんクリアする
    For i = 1 To 月末日 '変更した月末までのリストを作る
      .AddItem i
    Next i
  
    If 日 > 月末日 Then '前に選択していた日が変更した月末日を超える場合
      .ListIndex = 月末日 - 1 '変更した月末に変更する
    Else
      .ListIndex = 日 - 1 '前に選択していた日に戻す
    End If
  End With
  
End Sub

Private Sub cmb年_Change()

  If cmb月.Value = 2 Then '2月を選択していた場合
    '年の変更により,うるう年で月末日が変わるか確認する
    cmb月_Change '値は変えないが,Changeイベントを発生させる。
  End If

End Sub

【77983】Re:再び質問
発言  ichinose  - 16/2/23(火) 8:28 -

引用なし
パスワード
   ▼勤怠システムを自作したい さん:

>ここをVlookupで解決しようとしましたが訳がわからなくなってしまいました。
コンボボックスって優れものです。


新規ブック(Sheet1というワークシートがある)にて


Sheet1のセルA1からB5に以下のようなデータがあったとします。

 A         B
白岡あさ     あさが来たの主人公
白岡新次郎    あさの夫
白岡千代     おさの娘
白岡榮三郎    新次郎の弟
眉山はつ     あさの姉


ユーザフォームを一つ作ってください(UserForm1)

コンボボックス(ComboBox1)を一つ配置してください

Userform1のモジュールに

Option Explicit
Private Sub ComboBox1_Change()
  With ComboBox1
    If .ListIndex >= 0 Then
     MsgBox .List(.ListIndex, 0) & vbCrLf & .List(.ListIndex, 1)
    End If
  End With
End Sub
Private Sub UserForm_Initialize()
  With ComboBox1
    .Style = fmStyleDropDownList
    .List = Worksheets("sheet1").Range("a1:b5").Value
    .ColumnCount = 1
  End With
End Sub


標準モジュールに


Option Explicit

Sub test()
  UserForm1.Show
  
End Sub

testを実行し、UserForm1を表示させ、コンボボックスを選択してください。

対応したメッセージも表示されます。

このように使うと 検索機能が不要です。

【77984】Re:再び質問
発言  勤怠システムを自作したい  - 16/2/23(火) 12:06 -

引用なし
パスワード
   ▼ichinose さん:
回答有り難うございます、しかしこれだとユーザーフォーム上にデータが残らずに、メッセージボックスが出たままになってしまいますよね。
今回やらなければならないことはコンボボックスの内容に応じてユーザーフォームにあるラベルの表示内容を変えることなので、やはりvlookupが必要なのではないでしょうか。

【77985】Re:再び質問
発言  β  - 16/2/23(火) 19:24 -

引用なし
パスワード
   ▼勤怠システムを自作したい さん:

失礼します。

ichimoseさんが言っておられるのは、コンボボックスで選ばれた値を元に
シートをVKOOKUPする必要はさらさらなく、コンボボックスのリストとして
名前とともに、別の情報をセット(つまり見た目は1列のコンボボックスだけど実際は2列)しておけば
その2列目を直接参照できますよということだと思います。

MsgBox云々とは全く関係のないところです。
(その コード中のMsgBox の意味もわかりませんが)

ただ、この2列目の情報は、実行タイミングで、値が刻々変化しているものなのかもしれませんね。
であれば、コンボボックスの2列目にシート上の行番号をセットしておく手もあります。
そうすれば、やはり VLOOKUPを使わず、直接、選ばれた名前の行の特定セルの参照ができますので。

【77986】Re:再び質問
発言  β  - 16/2/23(火) 19:52 -

引用なし
パスワード
   ▼勤怠システムを自作したい さん:

で、質問は何でしょうか?

名前をコンボボックスで選択したら、シートのどこかにある AさんやBさんの、何をどうしたいのですか?
コードを一生懸命おいかけて理解しようとしましたが、要件がまったくわからないのでやめました。
現在時刻を表示しながら 年月日を選択する意味もよくわかりませんし。

【77987】Re:再び質問
発言  yuto  - 16/2/23(火) 20:16 -

引用なし
パスワード
   >▼勤怠システムを自作したい さん:

コンボボックスで指定された人ごとにシートが違うのか?
月ごとにシートが違うのか?といったようなシートのレイアウト
がないと話が進まない気がしています。

ちなみに質問とは関係ありませんが、月末日を算出するなら
以下のような記述もあります。

' 月末日を算出するための式
LastDate = CInt( Day( DateSerial ( Year(Now(), Month( Now() +1), 0)))

【77991】Re:再び質問
発言  ichinose  - 16/2/24(水) 6:55 -

引用なし
パスワード
   ▼勤怠システムを自作したい さん:
>今回やらなければならないことはコンボボックスの内容に応じてユーザーフォームにあるラベルの表示内容を変えることなので、やはりvlookupが必要なのではないでしょうか。
私間違えてました。
名前で検索するのではないのですね!!
名前は、シートの特定ですね これでシート分け・・・、vbaを使うなら、
必要ないと思いますけどね!! VBAを使うなら、データベースの構造は簡単な方が良いと思います。


で、日付でその日のデータを検索するということですか?

日付の検索は 書式によって難しいことがありますから、
書式のを確認しながら行ってみてください。

もっともInitializeイベントうんぬんは、ここで何をしたいのかわかりませんが・・。

ひょっとして、既定Aさんの本日の日付だから、そのデータを
表示させたいということでしょうかね!!

だとしても、日付の書式の問題が影響しそうです。

【77992】Re:再び質問
発言  β  - 16/2/24(水) 7:36 -

引用なし
パスワード
   ▼ichinose さん:

>日付の検索は 書式によって難しいことがありますから、
>書式のを確認しながら行ってみてください。
>

そうなんですよね。日付検索はフィルター関連も含めやっかいですね。
私の経験でいえば効率は悪いのでしょうけど、ワークシート関数のMATCHを使い
検索値にValue2を与えれば、検索できると思います。

【77993】Re:再び質問
質問  勤怠システムを自作したい  - 16/2/24(水) 11:53 -

引用なし
パスワード
   たくさんの返答を頂きありがとうございます。
やりたいことを分かりやすく伝えるというのは難しいことですね。

ユーザーフォームがないと説明しにくいのでフォームの画像を用意してみました。
://ur0.link/sfUQ

各種ボックスやラベルの配置がこのようになっており、目的は勤怠システムの構築です。
左上から順番に解説していくと、
日付→任意で変更できるが起動時に今の日付を自動取得
名前の選択→操作する人を取得
操作オプションの選択→打刻操作の制御
タイマー→今のリアルタイム時刻を表示しているだけ
実行ボタン→操作オプションに応じた操作を実行しそのデータを名前に一致したシートのセルに格納していく(例えばシート名でAさんというものがあり、Aさんが操作で出勤を選択し、実行を押した場合、日付ボックスに該当する日付をシートAさんから検出し、操作オプションに合わせたところに現在時刻を格納していきます。)
わかりにくいのでシートの配列も画像にしました→://ur0.link/sfXT

そして例としてC3、D3、E3、F3にデータが格納されていますが、今回質問しているのはこのデータを日付及び名前をフォーム上のコンボボックスで選択することで、シート上に該当するデータが有った場合はそのデータをlabel15,16,17,18(画像ではラベルをコピーしたので全部15になってますが)にそれぞれ表示するということですね。データがなければ空白が出力されます。
なので過去の日付が選択されていればその日のその人のデータをフォーム上に表示することが出来るようになります。

伝わりますでしょうか。

【77994】Re:再び質問
発言  ichinose  - 16/2/25(木) 2:11 -

引用なし
パスワード
   一例です。

新規ブックにて

標準モジュールに

Sub mk_sample()
  With Range("a1:b10")
    .Formula = Array("=datevalue(""2016/2/1"")+row()-1", "=char(64+row())")
    .Value = .Value
  End With
End Sub


上記のmk_sampleで作成したデータを日付で検索することを考えると・・・、


Sub test()
  MsgBox Application.VLookup("2016/2/5", Range("a1:b10").Value, 2, False)
  MsgBox Evaluate("vlookup(datevalue(""2016/2/6""),a1:b10,2,false)")
End Sub

こんな方法があります。

【77999】Re:再び質問
発言  β  - 16/2/27(土) 19:59 -

引用なし
パスワード
   ▼勤怠システムを自作したい さん:

コード自体のアドバイスは ichinose さんにおまかせして。
やはり ??? です。

たとえば今日、2/27 に操作したとします。
で、コンボボックスで年月日を自由に指定できるということなので
2/24 を指定したとします。
きっと、2/24分の 出勤時刻や退勤時刻等を入力したいんでしょうね。

で、一方、リアルタイム時刻が表示されていますね。
その時刻が 10:00 だったとします。10:01 、10:02、・・と、どんどん変わっていっていますが
2/24の出勤時刻は 9:00 だったとします。
そうすると、操作する人は リアルタイムが 9:00 になるまで、ず〜〜っと、23時間ほど待つのでしょうか。
で、9:00になった、よし、入力 というところで、もたもたして 9:01 になった。
わぁ、だめだということで、また 24時間待つのですか?

【78000】Re:再び質問
発言  ichinose  - 16/2/28(日) 15:46 -

引用なし
パスワード
   ちょっと訂正です。

>
>標準モジュールに
>
>Sub mk_sample()
  With Range("a1:b10")
    .Columns(1).NumberFormatLocal = "yyyy/m/d"
    .Formula = Array("=datevalue(""2016/2/1"")+row()-1", "=char(64+row())")
    .Value = .Value
  End With
>End Sub
書式設定しないと 日付に見えませんでした

>
>
>上記のmk_sampleで作成したデータを日付で検索することを考えると・・・、
>
>
>Sub test()
>  MsgBox Application.VLookup("2016/2/5", Range("a1:b10").Value, 2, False)
>  MsgBox Evaluate("vlookup(datevalue(""2016/2/6""),a1:b10,2,false)")
>End Sub
>
>こんな方法があります。

844 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free