Excel VBA質問箱 IV

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

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


223 / 3841 ページ ←次へ | 前へ→

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

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

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

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

' 月末日を算出するための式
LastDate = CInt( Day( DateSerial ( Year(Now(), Month( Now() +1), 0)))
・ツリー全体表示

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

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

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

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

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

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

失礼します。

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

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

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

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

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

【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を表示させ、コンボボックスを選択してください。

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

このように使うと 検索機能が不要です。
・ツリー全体表示

【77982】Re:別ファイルにあるセル範囲を配列に格...
お礼  ayu  - 16/2/23(火) 5:45 -

引用なし
パスワード
   ▼β さん:
短時間にたくさんコメント頂き本当にありがとうございます。教えて頂いた方法でやってみて、また結果をご報告します。
取り急ぎお礼にて

>▼ayu さん:
>
>もう1つ。
>転記レイアウトは アップ済みのものとはかえてあります。
>外部参照数式を使い、ブックを開かないタイプ。
>処理上もループをなくしてあります。
>元ブックのフォルダは、アップ済みのもの同様、マクロブックと同じフォルダにしてあります。
>
>Sub Sample2()
>  Dim fPath As String
>  Dim ref As String
>  Dim shT As Worksheet
>  Dim r As Range
>  
>  fPath = ThisWorkbook.Path
>  ref = "='" & fPath & "\[元のブック.xlsx]該当のシート名'!"
>  Set shT = ThisWorkbook.Sheets("転記先のシート名")
>  shT.Cells.ClearContents   '転記前にクリア
>  shT.Range("A1:F1").Formula = ref & "A2"
>  shT.Range("A2:F2").Formula = ref & "A9"
>  shT.Range("A1:F2").Value = shT.Range("A1:F2").Value
>  
>  With shT.Range("A2:F2")
>    .Replace 0, Empty, xlWhole
>    On Error Resume Next
>    .SpecialCells(xlCellTypeBlanks).EntireColumn.Delete
>    On Error GoTo 0
>  End With
>  
>End Sub
・ツリー全体表示

【77981】Re:2010と2013で差込印刷の挙動が違います
お礼  りのふぁん  - 16/2/22(月) 23:11 -

引用なし
パスワード
   ありがとうございました。
シートを特定したら正しい挙動になりました!

なんで2010では特定しなくてもよかったのかは謎のままですが。
・ツリー全体表示

【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
・ツリー全体表示

【77979】Re:別ファイルにあるセル範囲を配列に格...
発言  β  - 16/2/22(月) 13:13 -

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

もう1つ。
転記レイアウトは アップ済みのものとはかえてあります。
外部参照数式を使い、ブックを開かないタイプ。
処理上もループをなくしてあります。
元ブックのフォルダは、アップ済みのもの同様、マクロブックと同じフォルダにしてあります。

Sub Sample2()
  Dim fPath As String
  Dim ref As String
  Dim shT As Worksheet
  Dim r As Range
  
  fPath = ThisWorkbook.Path
  ref = "='" & fPath & "\[元のブック.xlsx]該当のシート名'!"
  Set shT = ThisWorkbook.Sheets("転記先のシート名")
  shT.Cells.ClearContents   '転記前にクリア
  shT.Range("A1:F1").Formula = ref & "A2"
  shT.Range("A2:F2").Formula = ref & "A9"
  shT.Range("A1:F2").Value = shT.Range("A1:F2").Value
  
  With shT.Range("A2:F2")
    .Replace 0, Empty, xlWhole
    On Error Resume Next
    .SpecialCells(xlCellTypeBlanks).EntireColumn.Delete
    On Error GoTo 0
  End With
  
End Sub
・ツリー全体表示

【77978】Re:別ファイルにあるセル範囲を配列に格...
発言  β  - 16/2/22(月) 9:44 -

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

↑ 元のブックはマクロブックと同じフォルダにあるという前提のコードです。
・ツリー全体表示

【77977】Re:別ファイルにあるセル範囲を配列に格...
発言  β  - 16/2/22(月) 9:35 -

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

たとえば以下で試してみてください。
どうしても、遅い!! ということなら別途の方法を考えましょう。

Sub Sample()
  Dim shF As Worksheet
  Dim shT As Worksheet
  Dim x As Long
  Dim c As Range
  
  Application.ScreenUpdating = False '処理中の画面の動きを隠す
  
  Set shF = Workbooks.Open(ThisWorkbook.Path & "\元のブック.xlsx").Sheets("該当のシート名")
  Set shT = ThisWorkbook.Sheets("転記先のシート名")
  
  shT.Cells.ClearContents   '転記前にクリア
  x = 1            '転記開始行
  
  For Each c In shF.Range("A9:F9")  '元ブックの合計行のセルの取り出し
    If c.Value > 0 Then       ' 0 超なら
      shT.Cells(x, "A").Value = c.EntireColumn.Cells(2).Value   '項目名
      shT.Cells(x, "B").Value = c.Value              '合計数
      x = x + 1  '次の転記行
    End If
  Next
  
  shF.Parent.Close False '元ブックを閉じる
    
End Sub
・ツリー全体表示

【77976】Re:別ファイルにあるセル範囲を配列に格...
発言  β  - 16/2/22(月) 9:19 -

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

質問文とレイアウトをよく見ましたら
ブックを開いて処理するなら、特段、データを取り込まなくても、直接元ブックを参照しながら
結果のみを表示するということができますね。
・ツリー全体表示

【77975】Re:別ファイルにあるセル範囲を配列に格...
発言  β  - 16/2/22(月) 9:12 -

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

>まず私がやろうとしている事は可能でしょうか?また他に簡単な方法があればお聞きしたいです。

はい。可能です。
データ件数にもよりますが、配列にいれずとも、直接、取り込み側シートにコピペして処理しても
処理速度にそんなに影響はないと思いますし、配列に入れることで、列単位の計算等が窮屈になります。
セル領域に取り込めば、非常に楽というか、柔軟な処理が望めます。

>ちなみに参照先のファイルは閉じた状態で見たいですが、かえって処理が遅くなったりするのでしょうか?

よく、この要望がだされます。
とくに、膨大なサイズのブックを相手にする。だから開くのが重くなるので、開かずに処理したい。
そこで、多くの人がイメージされるのが ExecuteExcel4Macro の利用。
ブックを開かずにセルのデータを取り出せる機能ですので。

最近、別の板ですけど、このあたりの検証が行われました。

www.excel.studio-kazu.jp/kw/20151023213330.html

結論としては

・膨大なブックであれば 
 ADO方式-->外部参照数式方式
 -- がく〜んと効率が悪くなって --> ExecuteExcel4Macro方式
 -- さらに効率が悪くなって --> ブックを開く方式

・通常のサイズのブックであれば、
 ADO方式-->外部参照数式方式-->ブックを開く方式
 -- がく〜んと効率が悪くなって --> ExecuteExcel4Macro方式

ブックサイズがいかほどかはわかりませんが、普通のエクセルブックであれば、ブックを開いて処理しても、
ADO方式や外部参照数式に比べて、そんなに効率には差がでません(少なくとも気になる差でなはい)

ADO方式や外部参照数式方式は確かに早いのですが、取得するためのコードが、ちょっと面倒になります。
当面のお勧めは、素直にブックを開いてセル領域をコピペで取り込んで処理 ですね。
・ツリー全体表示

【77974】別ファイルにあるセル範囲を配列に格納し...
質問  ayu  - 16/2/22(月) 8:23 -

引用なし
パスワード
   こんにちは。色々調べても自力では分からないのでこちらに質問させて頂きます。あるファイルに下記のようなデータが縦続きに数個入っています。日々の集計を取るために、2行目のメニュー名称と9行目にある各メニューの合計数がゼロ以上のものを別ファイルに該当メニューとその合計数を表示したいのですが、やり方としては下記のような事を考えています。

このファイルのメニュー名称が入っているセル範囲(A2:F2)と合計数(A9:F9)を、配列にコピーして、合計数が0以上のメニュー名とその数を表示したいと考えています。色々自分なりに調べてやってみたのですがうまく行きませんでした。
そこでお聞きしたいのは、まず私がやろうとしている事は可能でしょうか?また他に簡単な方法があればお聞きしたいです。ちなみに参照先のファイルは閉じた状態で見たいですが、かえって処理が遅くなったりするのでしょうか?ラップトップが遅いのでなるべく時間のかからないメモリの負荷が少ない処理だとありがたいです。

以上、ご教授のほどよろしくお願い致します。


    A列   B列  C列   D列  E列  F列
1行目 カットメニュー                    
2行目 カットA カットB カットC カットD カットE カットF
3行目 0    0    0    0    0    0
4行目 13    1    0    0    0    0
5行目 10    1    0    3    0    1
6行目 6    0    0    0    0    0
7行目 4    1    1    6    0    0
8行目 0    0    0    0    0    0            
9行目 33    3    1    9    0    1
・ツリー全体表示

【77973】Re:2010と2013で差込印刷の挙動が違います
発言  γ  - 16/2/22(月) 7:08 -

引用なし
パスワード
   If Range("G" & i).Value = True Then
の判定が正当におこなわれているか確認していますか?

そこを含め2カ所だけ、シートの特定されていないところがありますね。
(標準モジュールに書かれているのであれば)シートの特定がないと
アクティブシートが指定されたことになりますが、
その辺は影響がありませんか?
・ツリー全体表示

【77972】2010と2013で差込印刷の挙動が違います
質問  りのふぁん  - 16/2/21(日) 23:52 -

引用なし
パスワード
   差込印刷すべく以下のようなものを作りました
これで自宅のEXCEL2010のパソコンではすべてうまく挙動しました。
10枚印刷したければ10枚印刷できます。

ところが、その他のパソコン、EXCEL2013で使用すると、
シート上のマクロ登録された印刷ボタンから印刷すると、
なぜか10枚印刷したくても2枚しか印刷されません。
繰り返しが2回しかされないのです。

VBA上でF5キーで起動するとうまく稼働します。
他のパソコン数台(全て2013)も同じです。
なにがおかしいのでしょうか。


Sub 印刷()
  
  Dim i As Long
  Dim myNo As Long
  
  trueCount = Range("G39")
 
  res = MsgBox(trueCount & "件全て印刷しますか?", vbYesNo + vbQuestion)
  If res = vbYes Then

    With Worksheets("印刷設定")
     
     
      For i = 6 To 36
      
        myNo = .Range("A" & i).Value
        myDay = .Range("C" & i).Value
          
        If Range("G" & i).Value = True Then
          With Worksheets("TEST")
            .Range("H2").Value = myNo
            .Range("I2").Value = myDay
            .PrintPreview  '*******テスト用の行です
     '       .PrintOut Copies:=1, Collate:=True  '*******実際用の行です
            
          End With
        End If
        
      Next i
    End With
  End If
End Sub
・ツリー全体表示

【77971】Re:PowerPointファイルをmp4形式で保存し...
お礼  初学者オクダ  - 16/2/21(日) 19:53 -

引用なし
パスワード
   βさま

補足のアドバイス、誠にありがとうございます。
わざわざエラーを何度も起こしてデバックしていたため、今後はチェックするようにいたします。

また、参照設定についてもありがとうございます。
種類が数多くあったためどこをどういじったらよいのかわからなかったので、とても助かります。

深く御礼申し上げます。ありがとうございました!!

▼β さん:
>▼初学者オクダ さん:
>
>すでにichinoseさんから回答がありますので蛇足になります。
>
>モジュールの先頭に、Option Explict と記述する習慣を是非みにつけられたらよろしいかと思います。
>VBE画面のツール->オプション の編集タブの変数の宣言を強制する(R)にチェックをいれておくと
>モジュールを作った時に自動的に生成されます。
>
>こうしておけば、実行しようとした際(あるいは デバッグ->コンパイル)にコンパイラーが
>この定数のようなものは定義されていませんよと教えてくれますから。
>
>Option Explicitがない状態ですから ppSaveAsMP4 という名前で、値が空白の Variant型のデータとして
>FileFormatに与えられる結果、実行時エラーになるわけです。
>
>なお、ichinoseさんがいわれるように ppSaveAsMP4 はエクセルでは定義されていませんので
>その値である 39 を指定しなければいけないわけですが
>参照設定で MicrosoftPowerPoint x.x ObjectLibrary にチェックしておくと
> ppSaveAsMP4 という名前を使うことができます。
・ツリー全体表示

【77970】Re:PowerPointファイルをmp4形式で保存し...
お礼  初学者オクダ  - 16/2/21(日) 19:49 -

引用なし
パスワード
   ichinoseさま

早々のご回答、本当にありがとうございました!!
仰る通り、39に書き換えたところ、無事解決しました。
かなりの数のファイル数があったので、とても助かりました!!!!

深く御礼申し上げます。ありがとうございました!

▼ichinose さん:
>>現在、ExcelVBAから特定フォルダ内のPowerPointをすべてmp4形式に変換しようと作業を進めております。
>
>>  objPPT.ActivePresentation.SaveAs FileName:="ファイルB.mp4", FileFormat:=ppSaveAsMP4
>
>msdn.microsoft.com/en-us/library/office/ff746500.aspx
>このFileFormatの値だけが問題なら、
>上記サイトで調べると、
>
>ppSaveAsMP4は、39ですから、39に置き換えてみてください。
>
>2013を持っているなら、オブジェクトブラウザーでも調べられます。
>
>ppSaveAsMP4は、PowerPointが保持するEnum定数ですから、何もしなければ、
>Excelでは、使えません
・ツリー全体表示

【77969】Re:PowerPointファイルをmp4形式で保存し...
発言  β  - 16/2/21(日) 19:39 -

引用なし
パスワード
   ▼初学者オクダ さん:

すでにichinoseさんから回答がありますので蛇足になります。

モジュールの先頭に、Option Explict と記述する習慣を是非みにつけられたらよろしいかと思います。
VBE画面のツール->オプション の編集タブの変数の宣言を強制する(R)にチェックをいれておくと
モジュールを作った時に自動的に生成されます。

こうしておけば、実行しようとした際(あるいは デバッグ->コンパイル)にコンパイラーが
この定数のようなものは定義されていませんよと教えてくれますから。

Option Explicitがない状態ですから ppSaveAsMP4 という名前で、値が空白の Variant型のデータとして
FileFormatに与えられる結果、実行時エラーになるわけです。

なお、ichinoseさんがいわれるように ppSaveAsMP4 はエクセルでは定義されていませんので
その値である 39 を指定しなければいけないわけですが
参照設定で MicrosoftPowerPoint x.x ObjectLibrary にチェックしておくと
ppSaveAsMP4 という名前を使うことができます。
・ツリー全体表示

【77968】Re:PowerPointファイルをmp4形式で保存し...
発言  ichinose  - 16/2/21(日) 19:15 -

引用なし
パスワード
   >現在、ExcelVBAから特定フォルダ内のPowerPointをすべてmp4形式に変換しようと作業を進めております。

>  objPPT.ActivePresentation.SaveAs FileName:="ファイルB.mp4", FileFormat:=ppSaveAsMP4

msdn.microsoft.com/en-us/library/office/ff746500.aspx
このFileFormatの値だけが問題なら、
上記サイトで調べると、

ppSaveAsMP4は、39ですから、39に置き換えてみてください。

2013を持っているなら、オブジェクトブラウザーでも調べられます。

ppSaveAsMP4は、PowerPointが保持するEnum定数ですから、何もしなければ、
Excelでは、使えません
・ツリー全体表示

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