VBAでワークシートの操作を制御する

このQ&Aのポイント
  • VBAを使ってワークシートの操作を制御したい初心者です。具体的には、従業員出勤表を1シートにまとめて管理する方法について教えてください。
  • 出勤表を作成後、フォームボタンを使って以下の機能を実現したいです:(1) 出勤表の年と月を取得し、重複するシート名がないか確認する (2) 重複するシート名がある場合は保存を中止する (3) 重複するシート名がない場合は出勤表の雛形をコピーし、新しいシートを作成して保存する (4) 出勤表の内容が変更された場合に再保存する
  • 上記の要件に基づいてVBAコードを書いたのですが、(4)の部分がうまくいきません。どのように修正すればいいでしょうか?
回答を見る
  • ベストアンサー

VBAでワークシートの操作を制御する。

はじめまして。 最近、VBAの勉強を始めたばかりの初心者です。 どうかご教授くださいますようお願いします。 ■内容: 現在、職場の従業員出勤表を作成しています。 ひと月分の出勤表を、1シートに任意の名前を付け、1ファイルで管理しようと考えています。 そこでお教え頂きたい事は‥ シート「出勤表雛形」で出勤表を作成後、同シートに配置したフォームボタン(保存ボタン)に 以下4点の機能を持たせたいと思っております。 (1):シート「出勤表雛形」の"A1セルの値"(出勤表対象年) & "A3セルの値"(出勤表対象月)で ワークシート名を取得すると同時に、同ファイルに重複シート名が無いか確認する。 (2):重複シート名があれば、「対象の出勤表は既に作成済みです。」のメッセージを表示し、保存を中止する。 (3):重複ワークシート名が無ければ、シート(出勤表雛形)をシート最後尾にコピーし、 "A1セルの値" & "A3セルの値"でシート名を付けてフィル(出勤表.xls)を上書き保存する。 (4):(3)のシート上の保存ボタンで改め保存する場合は、ファイル(出勤表.xls)を上書き保存する。 ※後に訂正が生じた場合の為。 ※下記に現状で分かる範囲の構文を書きました。 (4)に関しては、自身でも調べてみましたが分かりませんでした。 また、不要、不足の部分が多々あり、大変見にくい構文かも知れませんがご参考までに見て頂ければと幸いです。 --------------------------------------------------------------- Sub ボタン保存_Click() '(1)新規に作成するシート名の重複確認 Dim ws As Worksheet, flag As Boolean  For Each ws In Worksheets If ws.Name = Range("A1").Value & Range("A3").Value Then flag = True Next ws If flag = True Then  '(2)重複シートありのメッセージ表示 MsgBox "対象の出勤表は既に作成済みです。", vbInformation  Else '(3)出勤表雛形ワークシートをコピーしてシート名の取得&保存  sheets("出勤表雛形").Copy After:=sheets(sheets.Count) sheets("出勤表雛形(2)").Select sheets("出勤表雛形(2)").Name = sheets("出勤表雛形(2)").Range("A1").Value & Range("A3").Value ThisWorkbook.Save endif end sub --------------------------------------------------------------- 以上。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

何が問題なのか書いていませんが、(4)の上書き保存しようとすると(1)の条件で撥ねられることが問題なのでしょうか。そうだとすると、 >For Each ws In Worksheets の前に以下のコードが必要かと。 If ActiveSheet.Name = Range("A1").Value & Range("A3").Value Then ThisWorkbook.Save Exit Sub End If

pink-amigo
質問者

お礼

早々のご回答ありがとうございます。 何が問題なのか、説明が不足しておりました。 大変、申し訳ございません。 この度の問題は、cistronezk様がおっしゃる通りです。 (4)の上書保存がしたかったのですが、(1)の段階で撥ねられておりました。 しかし、cistronezk様にお教え頂いた通り構文を訂正した所、当初の理想通りに動きました! 説明不足にも関わらず、ご回答頂けた事に感謝致します。 今後は基礎の勉強をすると共に、分からない事を教えて頂く時の聞き方にも注意を致します。

その他の回答 (1)

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.2

>制御する 初心者にしては、大げさな表現だが、もう少し具体的な内容の表題にしては。 ーー 私の例で、既に関数bというシートがあり Sub test04() Worksheets.Add.Name = "関数b" End Sub を実行すると、エラーになります。 同一ブックでは同名のシートはそもそも許されないのでは。 存在を前提にしてチェックする ボタン保存_Clickはなに? 作る前のチェック?別にシートが出来て、そこのA1,A3の値が無いのは どういうこと、あとから付け加える?==>わかりました。雛形に年月を入れてコピーするのですね。空白雛形をコピーしコピー後の名前を変えるほうが自然では。 Sub Sample05() On Error GoTo err1 Worksheets("Sheet2").Copy After:=Worksheets(Sheets.Count) ActiveSheet.Name = "aaaa" '作りたいシート名を別途セット End err1: MsgBox "重複" ActiveSheet.Delete End Sub 作りたいシート名はInputBoxででも入れさせたら。 OKならその名をA1,A3にセットする。 (4)など、実際にやってみて、マクロの記録を採って見れば判るのでは。

pink-amigo
質問者

お礼

迅速なご回答ありがとうございます。 表題、本文共に分かり難い表現に加え、説明も不足しておりました。 申し訳ございません。 この度の出勤表は‥ 雛形シートに年(A1セル)月(A3セル)を入れて、 その年月をシート名とした時に、重複シートが無いか確認する⇒ 重複無ければ、雛形シートをコピー⇒ コピーシートは、入力した年月で改め名前を付ける⇒ 雛形シートに戻り、入力範囲のセルをクリアして、次回ファイルを開いた時に、空の雛形シートから新規作成を始めるようにする。⇒ また、作成したシートを後から編集し保存した場合はファイルを上書きする。⇒ ‥といった流れで作ろうと考えていました。 しかし、imogasi様のご指摘通り、 空白雛形をコピーして、コピー後の名前を変えるのが自然だと気付きました。 今後の為にも、ご指摘頂いた所とVBAについての基礎を勉強して行きます。

関連するQ&A

  • 【Excel VBA】シート表示&ボタン操作

    何度もすみません。 シート表示のコードの続きです。 また、別記事で質問していた件(件名の後者)も合わせて コードに組み込んでいます。 Sheets(actsht).Tab.ColorIndex = 2 '当月分のワークシート見出しの色を白に設定する Sheets(actsht).Range("B3").Value = Sheets("Sheet2").Range("A1").Value 'ワークシート(Sheet2)のA1セルの値を当月分のワークシートのB3セルに代入 Sheets(actsht).Range("B4").Value = Sheets("Sheet2").Range("A2").Value 'ワークシート(Sheet2)のA2セルの値を当月分のワークシートのB4セルに代入 ActiveSheet.Range("A2").Select '翌月分のワークシートのA2セルを選択する Sheets("元データ").Visible = True 'ワークシート(元データ)を表示する Call clear_Click 'フォームボタン(clear)をクリックする Sheets("元データ").Visible = False 'ワークシート(元データ)を非表示にする Exit For 'For文を抜ける ElseIf Anser = vbNo Then 'MsgBoxで"vbNo"を選択した場合 Exit For 'For文を抜ける End If 'If文を終了する End If 'If文を終了する Next 'iの値を1増分する If Flag = O Then 'Flagが0であった場合 MsgBox ("新しいワークシートを作成出来ません。") 'MsgBoxを表示する End If 'If文を終了する End Sub

  • 【Excel VBA】ワークシートの表示(続き)

    すみません。 追記が出来なかったため、コードの続きをこちらに記載します。 For i = 1 To 12 If actsht = tmp(i) Then Flag = 1 Anser = MsgBox("翌月分シートを作成しますか?", vbYesNo + vbDefaultButton1, "確認") If Anser = vbYes Then ActiveSheet.Copy After:=ActiveSheet ActiveSheet.Name = tmp(i + 1) Sheets(actsht).Tab.ColorIndex = 2 Sheets(actsht).Range("B3").Value = Sheets("Sheet2").Range("A1").Value Sheets(actsht).Range("B4").Value = Sheets("Sheet2").Range("A2").Value ActiveSheet.Range("A2").Select Exit For ElseIf Anser = vbNo Then Exit For End If End If Next If Flag = O Then MsgBox ("新しいワークシートを作成出来ません。") End If If actsht = tmp(i) Then If Sheets(元データ).Visible = False Then Sheets(元データ).Visible = True End If End If End Sub

  • Excel VBAで…。

    データーシート(1)のデータをレイアウトシート(2)に転記するのに 例えば sheets(1).range("A1").value=sheets(2).range("C5").value sheets(1).range("B1").value=sheets(2).range("C6").value sheets(1).range("C1").value=sheets(2).range("C7").value と言うように配置しているのですが もし、シート(1)セルB1の値が空白ならば シート(1)セルC1の値はシート(2)のセルC6に配置・・・ と言うように データがない場合は、転記後の配置は詰めて配置したいのです。 どうすればよろしいでしょうか?

  • VBA中の”シート名”を”アクティブシート”に変更

    いつもお世話になっております。 非常に初歩的な質問なのですが、下記の2つのVBA中のシート名をアクティブシートに変更したいのですが、 sheetName = ActiveSheet.Name で試行錯誤するもうまくいきません。 実際のコードは下記の通りです。 これらのシート名”申請書”をアクティブシートに変更したいのです。 このコードは過去にここで教えて頂いたコードで出来ればこれを修正したいので宜しくお願いします。 1.Sub 申請書登録() Dim NewBookName As String With ThisWorkbook.Sheets("申請書") Windows("1.新規・変更登録申請書(原紙)・リスト②T用.xlsm").Activate For i = 5 To Sheets("規格登録・変更リスト").Range("A1048576").End(xlUp).Row + 1 If Sheets("規格登録・変更リスト").Range("B" & i).Value = "" Then With Sheets("規格登録・変更リスト") .Range("A" & i).Value = Sheets("申請書").Range("E3").Value .Range("B" & i).Value = Sheets("申請書").Range("O3").Value .Range("C" & i).Value = Sheets("申請書").Range("E4").Value ・・・・・・・・・・・・・・・・・・・ 2.Sub 申請書保存() Dim NewBookName As String With ThisWorkbook.Sheets("申請書") NewBookName = .Range("F22").Value & " " & .Range("E4").Value & " " & .Range("A2").Value & " " & .Range("A1").Value Worksheets("申請書").ExportAsFixedFormat Type:=xlTypePDF, Filename:="\***\XXXX\1.申請書\申請書" & "\" & NewBookName End With End Sub

  • VBAでシート名をセルから取得したいのですが

    データシートが数枚あり、そこから、シートごとに必要なデータのみ抽出して、印刷用シート(1枚)にまとめて書きこみたいと思っています。 書きこみは以下のような感じにしています。 Sheets("印刷用シート").Activate Range("A1").Value = Sheets("データ1").Range("A1").Value ここで、データ1というシート名を、色々に変えたいのです。 印刷用シートのセルに「データ1」なり「データ2」なり入力したら、その部分が変わるように変数にしたいのですが、どのようにすればいいでしょうか? VBAを勉強中(初心者)です。よろしくお願いします。

  • エクセル VBA シートの選択 

    windows XP でエクセル2000を使っています。 Sub aaa() Sheets("Sheet1").Select Dim a As String a = Cells(2, 4) Sheets(a).Select Range("A1").Select End Sub というマクロだと セルに入っている値のシート名を探してくれます。 ですが Private Sub Worksheet_SelectionChange(ByVal Target As Excel.Range) If Intersect(Target, Range("B11:b683")) Is Nothing Then Exit Sub Worksheets("Sheet1").Range("C2").Value = Target.Value Dim b As String b = Range("C2).value (←ここをcellsにしてもダメ) Sheets(b).Select Range("A1").Select End Sub これだとsheets(b)を選びません。Sheets(b).Selectのところが黄色くなります。 何処が間違えているのでしょうか。 全くの素人ですが、仕事で必要に迫られています。 わかりやすく回答・解説くれると助かります。

  • EXCELでSheetにデータを蓄積したい

    Sheet1に入力シートを作成し、Sheet2に蓄積シートを作成しました。 Sheet1で作成されたデータをSheet2に蓄積させておきたい。 Sheet1のA2の値が入力された場合に実行するとすると Sheet1のデータ数は、毎回異なります。 他を参考に以下のように作ってみたのですが、 Private Sub Worksheet_Change(ByVal Target As Range) Dim lastA As Long, lastB As Long, ws1 As Worksheet, ws2 As Worksheet Set ws1 = Sheets("入力シート") Set ws2 = Sheets("蓄積シート") With Target If .Address <> "$A$2" Or .Count <> 1 Or IsEmpty(Target) Then Exit Sub If WorksheetFunction.Count(ws1.Range("a1:s1")) <> 19 Then Exit Sub lastA = ws2.Range("a65536").End(xlUp).Row lastB = ws1.Range(("a2:s2"), Selection.End(xlDown)).Select ws2.Range("a" & lastA + 1).Resize(1, 19).Value = _ ws1.Range("a2:S2").Resize(1, 19).Value End With End Sub 'ws1.Range("a2:S2").Resize(1, 19).Value の部分で '上記ws1の範囲の内、Row2の値しかws2へ反映されません どなたか教えて頂けないでしょうか。

  • ワークシートのChangeイベントについて

    シート1のA1セルの値を変更したらシート2のA1・A2・A3と変更内容を順に記録するような以下のようなコードがありますが、うまく動作しません。問題点を指摘していただければ大変助かります。 【Worksheet】 Private Sub Worksheet_Change(ByVal Target As Range) Static r Dim s As Range Set s = Sheets("sheet1").Range("$a$1").Value If s Is Nothing Then Else If r = "" Then r = 1 Sheets("sheet2").Cells(r, 1) = Sheets"sheet1").Range("$a$1").Value r = r + 1 End If End Sub

  • VBA コマンドボタンにおけるコードについて

    下記のようなコードを作成しました。 これを簡略化するにはどうすれば良いのでしょうか? よろしくお願いします。 Private Sub CommandButton1_Click() Sheets("sheet2").Select Select Case UserForm1.ComboBox1.Text Case Is = Sheets("sheet2").Range("A1").Value Sheets("sheet2").Range("B1").Value = "X" Case Is = Sheets("sheet2").Range("A2").Value Sheets("sheet2").Range("B2").Value = "X" Case Is = Sheets("sheet2").Range("A3").Value Sheets("sheet2").Range("B3").Value = "X" Case Is = Sheets("sheet2").Range("A4").Value Sheets("sheet2").Range("B4").Value = "X" Case Is = Sheets("sheet2").Range("A5").Value Sheets("sheet2").Range("B5").Value = "X" ・ ・ ・ End Select End Sub

  • シートを増やすVBA

    フィルタで隠れている場合もある列の値を シート名として増やしていくVBAで以下のようなものをつくりました (値は重複している場合もある) 雛型シートがありそれをシート名だけ増やしていくというものです Sub シートを増やす() Dim target As Range Dim h As Range On Error Resume Next Set target = Worksheets("一覧シート").Range("E10:E" & Worksheets("一覧シート").Range("E65536").End(xlUp).Row).SpecialCells(xlCellTypeVisible) If target Is Nothing Then Exit Sub 'シートを増やしていく For Each h In target On Error GoTo errhandle Worksheets(h.Value).Select On Error GoTo 0 Next Sheets("一覧シート").Select Exit Sub errhandle: Worksheets("雛型").Copy after:=Worksheets(Worksheets.Count) ActiveSheet.Name = h.Value Resume End Sub そうすると、実行エラー1004 ”シートの名前をほかのシート、Visual Basicで参照されるオブジェクトライブラリまたはワークシートと同じ名前に変更することはできません。” というエラーがたまにおきます(シート名が数字の場合におきるようです) 解決方法及び理由をご教授ください

専門家に質問してみよう