Access (VBA)

Access VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 7 Professional : Access 2010)
時間を指定した作業指示
投稿日時: 17/10/19 16:00:46
投稿者: おで

教えてください
検査部門の作業指示を時間単位で行いたい。
 
イメージ的には、下記のようなもので、それぞれの作業時間が検査工数から算出できないか?と
考えております
 
(No.)(商品名)(検査工数_分)(作業時間)
1   A     40      9:00〜9:40
2   B     30      9:40〜10:20 ・・・※1
3   C     60      10:20〜11:20
4   D     60      11:20〜13:20 ・・・※2
・   ・     ・         ・
 
ただ、休憩時間が
10:00〜 10分
12:00〜 60分
15:00〜 10分
とあるため、上記※1・2のように休憩時間を考慮した時間算出が必要です。
VBAで条件を考えながら作成しておりましたが、意図した結果が得られず、ここに投降した次第です。
宜しくお願い致します

回答
投稿日時: 17/10/19 17:49:50
投稿者: je6iht

 最初からVBAで考えずに、図を描いて検討したらよいです
 
始業時刻----10時の休憩-----昼休み-----3時の休憩------終業時刻 
 
のように描いてどのようなパターンが考えられるかを検討してください
工数時間もここに提示してあるだけでしょうか、いろいろなパターンを考える必要が有ると思います
また。終了予定時刻が、就業時間を超過した時はどうするか?
早出時間とかはないのですか
工数の時間が110分を超える(二つの休み時間を跨ぐ)ことはないのですか?

投稿日時: 17/10/20 08:19:23
投稿者: おで

コメントいただきまして、ありがとうございます
まずは、パターンの洗い出しをしてみることにします
 
 
>終了予定時刻が、就業時間を超過した時はどうするか?
 第一段階としては、そのまま提示しようと思います
 
>早出時間とかはないのですか
 早出時間はありません
 
>工数の時間が110分を超える(二つの休み時間を跨ぐ)ことはないのですか?
 超える可能性があります

回答
投稿日時: 17/10/20 14:29:13
投稿者: hatena
投稿者のウェブサイトに移動

パターンで考えると、かなりのパターン数になりそうですので、フローチャートを作成する方向の方がいいかも。
 
例えば、下記のような感じのフローになるかと。
 
1.開始時刻に、始業時刻(9:00)を代入

2.開始時刻に、検査工数_分をたして、終了予定時刻を計算

3.上記時間内に10時の休憩が含まれていたら、終了予定時刻に10分加算

4.上記時間内に昼休みが含まれていたら、終了予定時刻に60分加算

5.上記時間内に3時の休憩が含まれていたら、終了予定時刻に10分加算

6.終了時刻を変数に格納して、次のレコードへ移動

7.変数の終了時刻を、開始時刻に代入

以下、2.から7.を最終レコードまで繰り返し
 

回答
投稿日時: 17/10/21 02:30:06
投稿者: mayu.

VBA 板ですが、SQL で算出するサンプルを載せておきます。
 
■ テーブル定義
------------------------------------------------------------

CREATE TABLE t_num
(
      num INT NOT NULL PRIMARY KEY
);

 
CREATE TABLE t_検査
(
      cid          AUTOINCREMENT NOT NULL PRIMARY KEY
    , 日付         DATETIME      NOT NULL
    , 商品名       VARCHAR( 50 ) NOT NULL
    , 検査工数_分  SMALLINT      NOT NULL
);

 
CREATE TABLE t_休憩
(
      rid         AUTOINCREMENT NOT NULL PRIMARY KEY
    , 開始時刻    DATETIME      NOT NULL
    , 終了時刻    DATETIME      NOT NULL
);

 
CREATE TABLE t_稼働
(
      行番号      AUTOINCREMENT NOT NULL PRIMARY KEY
    , 時刻番号    INT           NOT NULL
    , 時刻        DATETIME      NOT NULL
);

 
 
■ データ例
------------------------------------------------------------
< t_num > ※ 0 〜 1439の連続した数値
-----------
   num
-----------
    0
    1
    2
   .
   .
   .
 1438
 1439

 
< t_検査 >
------------------------------------------
cid       日付       商品名   検査工数_分
------------------------------------------
1	2017/10/20	A	40
2	2017/10/20	B	30
3	2017/10/20	C	60
4	2017/10/20	D	60

 
< t_休憩 >
---------------------------------
rid	開始時刻	終了時刻
---------------------------------
1	10:00:00	10:10:00
2	12:00:00	13:00:00
3	15:00:00	15:10:00

 
■ SQL ( 順番に実行 )
------------------------------------------------------------
 
/*
 **********************************
 *
 *  一時テーブルのデータを全削除
 *
 **********************************
*/
DELETE FROM t_稼働 ;

 
/*
 *****************************************
 *
 *  一時テーブルのオートナンバーをリセット
 *
 *****************************************
*/
ALTER TABLE t_稼働 ALTER COLUMN 行番号 COUNTER ( 1, 1 ) ;

 
/*
 ***************************************************************
 *
 *  始業時間 と 終業時刻 を指定した上で
 *  休憩時間を抜いた作業対象全時刻を一時テーブルに追加
 *
 *  ( 一時テーブルを使わなくても結果を出すことは可能ですが
 *    重くなるため、相関サブクエリでの連番付与を回避します。 )
 *
 ***************************************************************
*/
INSERT INTO t_稼働 ( 時刻番号, 時刻 )
SELECT num, DateAdd( 'n', num, #00:00# )
FROM t_num x
WHERE num Between DateDiff( 'n', #0:00#, #9:00# ) 
              And DateDiff( 'n', #0:00#, #18:00# )
  AND NOT EXISTS
      (
          SELECT 1 FROM t_休憩 y
          WHERE DateAdd( 'n', x.num, #00:00# ) >= y.開始時刻
            AND DateAdd( 'n', x.num, #00:00# ) < y.終了時刻
      )
;

 
/*
 *********************************************************************
 *
 *  2017年10月20日の全作業時間を計算
 *
 *********************************************************************
*/
SELECT y.cid
     , y.日付
     , y.商品名
     , y.検査工数_分
     , Max( x.行番号 ) -  Min( x.行番号 ) + 
       IIf( 
            ( Max( x.行番号 ) - Min( x.行番号 ) ) Mod 5 > 0
          , 1, 0
       ) As 工数内訳
     , Min( x.時刻 ) As 作業開始時刻
     , DateAdd( 'n'
              , IIf( 
                     ( Max( x.行番号 ) - Min( x.行番号 ) ) Mod 5 > 0
                   , 1, 0
                )
              , Max( x.時刻 )
       ) As 作業終了時刻
FROM t_稼働 x
    ,
(
    SELECT t1.cid
         , t1.日付
         , t1.商品名
         , t1.検査工数_分
         , Sum( t2.検査工数_分 ) - t1.検査工数_分 + 1 As 開始範囲
         , Sum( t2.検査工数_分 )                  + 1 As 終了範囲
    FROM t_検査 t1
       , t_検査 t2
    WHERE t1.日付 = #2017/10/20#
      AND t2.日付 = #2017/10/20#
      AND t1.cid >= t2.cid
    GROUP BY t1.cid
           , t1.日付
           , t1.商品名
           , t1.検査工数_分
) y
WHERE x.行番号 Between y.開始範囲 And y.終了範囲
GROUP BY y.cid
       , y.日付
       , y.商品名
       , y.検査工数_分
       , x.時刻番号 - x.行番号
ORDER BY y.cid
       , Min( x.行番号 ) ;

 
■ 結果
------------------------------------------------------------------------------
cid     日付      商品名  検査工数_分  工数内訳  作業開始時刻  作業終了時刻
------------------------------------------------------------------------------
 1    2017/10/20     A        40          40       9:00:00        9:40:00
 2    2017/10/20     B        30          20       9:40:00       10:00:00
 2    2017/10/20     B        30          10      10:10:00       10:20:00
 3    2017/10/20     C        60          60      10:20:00       11:20:00
 4    2017/10/20     D        60          40      11:20:00       12:00:00
 4    2017/10/20     D        60          20      13:00:00       13:20:00

 
日付毎に 総検査工数 と 休憩時間 を合計すれば、残業の有無もわかりますし、
SQL文中で直書きしている 日付 や 時刻 は
パラメータに変更したり、VBAで埋め込むようにすればいいでしょう。

回答
投稿日時: 17/10/21 11:24:30
投稿者: hatena
投稿者のウェブサイトに移動

上の回答のフローをコード化してみました。
 
テーブルは、下記のようだとします。
 
テーブル
 T_検査
フィールド構成
 CID 数値型 作業順
 日付 日付/時刻型 検査日付
 商品名 テキスト型
 検査工数_分 数値型
 開始時刻 日付/時刻型
 終了時刻 日付/時刻型
 
データ例

CID	日付  	商品名	検査工数_分	開始時刻	終了時刻
1	2017/10/21	A	   40	09:00:00	09:40:00
2	2017/10/21	B	   30 	09:40:00	10:20:00
3	2017/10/21	C	   60	10:20:00	11:20:00
4	2017/10/21	D	   60	11:20:00	13:20:00

 
Public Sub 作業時間入力()
    Dim rs As DAO.Recordset
    Dim strDate As String
    Dim BeginTime As Date
    
    strDate = "2017/10/21" '検査日付
    BeginTime = #9:00:00 AM# '始業時刻
    
    Set rs = CurrentDb.OpenRecordset("SELECT * FROM T_検査 WHERE 日付=#" & strDate & "# ORDER BY CID")

    Do Until rs.EOF
        rs.Edit
        rs!開始時刻 = BeginTime
        BeginTime = DateAdd("n", rs!検査工数_分, BeginTime)
        If BeginTime > #10:00:00 AM# And rs!開始時刻 <= #10:00:00 AM# Then
            BeginTime = DateAdd("n", 10, BeginTime)
        End If
        If BeginTime > #12:00:00 PM# And rs!開始時刻 <= #12:00:00 PM# Then
            BeginTime = DateAdd("n", 60, BeginTime)
        End If
        If BeginTime > #3:00:00 PM# And rs!開始時刻 <= #3:00:00 PM# Then
            BeginTime = DateAdd("n", 10, BeginTime)
        End If
        rs!終了時刻 = BeginTime
        rs.Update
        rs.MoveNext
    Loop

End Sub

 
上記コードの実行結果
CID	日付  	商品名	検査工数_分	開始時刻	終了時刻
1	2017/10/21	A	   40	09:00:00	09:40:00
2	2017/10/21	B	   30	09:40:00	10:20:00
3	2017/10/21	C	   60	10:20:00	11:20:00
4	2017/10/21	D	   60	11:20:00	13:20:00

投稿日時: 17/10/22 18:22:37
投稿者: おで

hatenaさん、mayu.さん、ご回答いただきまして、ありがとうございます。
会社で試してみます。

投稿日時: 17/10/23 13:30:40
投稿者: おで

希望のデータが出力されるようになりました。
ありがとうございました!