- ベストアンサー
エクセルVBAでシート追加
初めて質問します。 VBAで新しいシートを追加する時 同名のシート等があるとエラーになります。 追加するときシート名をチェックしたいのですが どの様にすれば良いでしょうか? また、シートは一番最後に追加したいです。 よろしくお願いします。 Sub Macro1() x = InputBox("シート名") Worksheets.Add.Name = x End Sub
- オフィス系ソフト
- 回答数9
- ありがとう数5
- みんなの回答 (9)
- 専門家の回答
質問者が選んだベストアンサー
> また、シートは一番最後に追加したいです。 これを忘れてました。 Sub test01() x = InputBox("シート名") If LenB(x) > 31 Then MsgBox "名前が長すぎます。" Exit Sub End If For Each st In Worksheets If st.Name = x Then MsgBox "すでに同名のシートがあります。" Exit Sub End If Next On Error GoTo line Set ws = Worksheets.Add(after:=Worksheets(Worksheets.Count)) ws.Name = x Set ws = Nothing Exit Sub line: MsgBox "名前に不適切な文字があります。" End Sub
その他の回答 (8)
こんばんは kasoukenです シートを追加するだけのご質問ですが #多分これだけではないと思いますが 自分用ならNO1のmerlionXXさんが書かれている様にします。 他の方が使用するならクラスモジュールに書くと思います。 クラスモジュールに書く必要があるかは別にしてですが。 ようは、誰が使うかで使い分けています。 Wendy02さんも書かれていますが、 >この手のマクロというのは、必ず正しいシート名のシートを作らせるために作るのではないでしょうか? 本来のマクロの目的は、何かということですね。 だと思います。 Wendy02さん。引用させて頂きました。すいません。 あと、変数の宣言はした方が良いです。
お礼
ありがとうございました 参考にさせて頂きます またよろしくお願いします。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。#6 のWendy02です。 >個別にチェックするのは無駄なことなのでしょうか? その必要性があるかどうかです。しょせん、エラーはエラーで、そのエラーは、ユーザー本位の問題であって、それをマクロに依存するということは、無駄が多いと思います。以下で関数を作ってみましたので、ごらんください。ユーザー側の認識度だと思うのです。 >>それに、シートを追加するというユーザーの意思決定が、Excel側が、 >>名前が通らないので、取りやめるというロジックもヘンです。 >と書かれていますが、どうしてなのでしょうか? この手のマクロというのは、必ず正しいシート名のシートを作らせるために作るのではないでしょうか? 本来のマクロの目的は、何かということですね。シート名を判断させるためのものか、それとも、シートを加えるためのものか、ということです。楽にシートを加えるために作るのではないのですか?エラーが出たら、本来は、そのままシートを加えて、手で直させるとか、その程度で良いと思います。 実務的には、あまり、複雑なことをさせても、結果がシート1枚ですから、VBAのロジックとして、もう少し単純に考えたほうが、楽だと思います。ご自身のマクロの勉強というなら、ぜひ、がんばってみるのもよいかとは思いますが、盛りだくさんに考えても、回答者にとっても、ご自身にとっても限界があると思うのです。 そう言った手前、一応、おっしゃっていることをVBAで表現してみました。たぶん、このような感じになるのではないかと私は思います。さらに、エラーレベル(ErrorLevel) を、細かく分類することも可能ですし、まだ、細かい点が抜けているかもしれません。そういう不安さが残る内容です。 '----------------------------------------------------- Sub AddSheetMacro() Dim ShName As Variant Dim chk As Integer Dim msg As String 'エラーメッセージ Const MSG1 As String = "同名シートがあります" & vbCrLf Const MSG2 As String = "シート名がないか,半角空白か,シート名が長すぎます" & vbCrLf Const MSG3 As String = "シートでは使っていけない文字があります" & vbCrLf & _ "( : ),(\),(/), (?),(*), ([),(])" & vbCrLf ThisWorkbook.Activate ShName = Application.InputBox("シート名を入れてください", Type:=2) If ShName = "" Or VarType(ShName) = vbBoolean Then Exit Sub chk = ShNameCheck(ShName) If chk = 0 Then Worksheets.Add After:=Sheets(Sheets.Count) Else If chk = 1 Then msg = MSG1 ElseIf chk = 2 Then msg = MSG2 ElseIf chk = 3 Then msg = MSG3 Else msg = "複合的なエラーです" End If End If If Len(msg) > 0 Then MsgBox msg, vbInformation End If End Sub '標準モジュールに必ず置いてください Function ShNameCheck(ShName As Variant, Optional wb As Workbook) As Integer Dim flg As Boolean Dim ErrorLvl As Integer Dim dummy As Variant If wb Is Nothing Then Set wb = ActiveWorkbook On Error Resume Next dummy = wb.Worksheets(ShName).Range("A1").Value If Err.Number = 0 Then ErrorLvl = 1 End If On Error GoTo 0 If Len(ShName) < 1 Or Len(ShName) > 31 Or StrComp(ShName, " ", 0) = 0 Then ErrorLvl = 2 If ShName Like "*[:\?*/]*" Then ErrorLvl = 3 If (InStr(ShName, "[") Or InStr(ShName, "]")) > 0 Then ErrorLvl = 3 ShNameCheck = ErrorLvl End Function
お礼
Wendy02さん たびたびありがとうございます。 勉強になりました。 エラーについての認識を考えてみます。 これに懲りず機会があればアドバイスよろしくお願いします。
お邪魔します。 ありがちなチェック方法ですが関数作ってみました。 まだチェックする所があるかも・・・ Sub Smp1() Dim newSheName As String Dim AddSheet As Worksheet Dim cName As String newSheName = VBA.InputBox("シート名") If VBA.Len(newSheName) = 0 Then Exit Sub End If cName = NameCheck(newSheName) If cName = "OK" Then With Worksheets Set AddSheet = .Add(after:=.Item(.Count)) AddSheet.Name = newSheName Set AddSheet = Nothing End With Else MsgBox cName End If End Sub '--------------------------------------------- Function NameCheck(xName As String) As String Dim xShe As Worksheet On Error Resume Next Set xShe = Sheets(xName) If Not xShe Is Nothing Then NameCheck = "同名" Set xShe = Nothing Exit Function End If On Error GoTo 0 With CreateObject("VBScript.RegExp") .Pattern = "[\\/:\?\[\]\*]" If .Test(xName) Then NameCheck = "不可の文字あり" Exit Function End If End With If VBA.LenB(VBA.StrConv(xName, vbFromUnicode)) > 31 Then NameCheck = "31文字以内(半角)" Exit Function End If NameCheck = "OK" End Function
補足
ありがとうございます チェックできました。 少し教えてください Kasoukenさんは いつもこのようなエラーチェックをしているのでしょうか?
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 今、ちょっとレスの応答をみていて、こちらでも調べてみたのですが、なぜ、#1のmerlionXX さんや#2のzap35さんのコードでいけないのでしょうか?ロジックとして間違っていないはずです。 >同名のエラーや文字数の超過など個別に >チェックする方法は難しいのでしょうか? それらを個別にチェックすれば、確かにいくつかの該当する問題は出てくるのでしょうけれど、それらを事前に、個々にチェック関数やプロシージャを作るというのは、かなり面倒だと思います。 しかし、Excelを扱うユーザーとして、ある程度の常識的な中でシート名をつけるのであって、それが通るか通らないかは、最終的にExcelのApplication 任せにしてよいと思うのです。これは、オブジェクト指向にも通じることですが、ブラックボックス=結果論だと思います。 基本的には、Excelでは、ワークシート名が通るか通らないかの独自のVBA関数には用意されていないのです。出来ないわけではありません。確か、API関数に、ファイル名が有効かどうかの関数があったので、代用できるような気がしますが、シート名の仕様を全部調べて、そのエラーをユーザーにメッセージとして返すというのは、大変なことだと思います。 別の言い方をすると、シート名の決め事は、Excelの入門レベルの問題だと思うのです。もし、そういうユーザーを対象とするなら、シートを追加場合は、すでに、「キメウチ」でシート名をつけてしまうというのが良いと思うのです。 それに、シートを追加するというユーザーの意思決定が、Excel側が、名前が通らないので、取りやめるというロジックもヘンです。
補足
ありがとうございます 少し教えてください。 個別にチェックするのは無駄なことなのでしょうか? また、 >それに、シートを追加するというユーザーの意思決定が、Excel側が、 >名前が通らないので、取りやめるというロジックもヘンです。 と書かれていますが、どうしてなのでしょうか? 宜しくご教授お願いします。
- zap35
- ベストアンサー率44% (1383/3079)
#02です。文字数チェックと不適文字の置換を入れてみました Sub ShAdd() Dim x Dim LastSH, idx As Integer Dim ActSH As Worksheet Set ActSH = ActiveSheet x = Application.InputBox("シート名は?", 2) If x = False Then Else x = Replace(x, "/", "") '不適文字(例)を置換 x = Replace(x, "\", "") x = Replace(x, "*", "") x = Replace(x, "?", "") If Len(x) > 10 Then '文字数チェック MsgBox ("シート名は10文字以内にしてください") Exit Sub End If For idx = 1 To Worksheets.Count If Worksheets(idx).Name = x Then '重複名チェック MsgBox ("同名のシートが存在します") Exit Sub End If Next idx Worksheets.Add after:=Worksheets(Worksheets.Count) ActiveSheet.Name = x ActSH.Activate End If End Sub
お礼
ありがとうございます お手数をおかけ致しました。 色んな方法が有るのですね。 勉強になりました。感謝です。
- merlionXX
- ベストアンサー率48% (1930/4007)
> 同名のエラーや文字数の超過など個別に > チェックする方法は難しいのでしょうか? #1のmerlionXXです。 では、これではいかがでしょう? Sub test01() x = InputBox("シート名") If LenB(x) > 31 Then MsgBox "名前が長すぎます。" Exit Sub End If For Each st In Worksheets If st.Name = x Then MsgBox "すでに同名のシートがあります。" Exit Sub End If Next On Error GoTo line Worksheets.Add.Name = x Exit Sub line: MsgBox "名前に不適切な文字があります。" End Sub
- zap35
- ベストアンサー率44% (1383/3079)
マクロを書いてみました(少し大げさにしすぎたかもしれません) 重複名がある場合は「シート名-(2)」で追加します Sub ShAdd() Dim x Dim LastSH, idx As Integer Dim ActSH As Worksheet Set ActSH = ActiveSheet x = Application.InputBox("シート名は?", 2) If x = False Then Else For idx = 1 To Worksheets.Count If Worksheets(idx).Index = Worksheets.Count Then LastSH = idx End If If Worksheets(idx).Name = x Then x = x & "-(2)" End If Next idx Worksheets.Add after:=Worksheets(LastSH) ActiveSheet.Name = x ActSH.Activate End If End Sub
補足
ありがとうございます 説明不足で申し訳ございません 同名のシートがあれば追加しないです。 同名のエラーや文字数の超過など個別に チェックする方法は難しいのでしょうか?
- merlionXX
- ベストアンサー率48% (1930/4007)
いちいちシート名をチェックしなくともエラーを回避すればいいのですよね? Sub Macro1() x = InputBox("シート名") On Error GoTo line Worksheets.Add.Name = x Exit Sub line: MsgBox "すでに同名のシートがあるか、名前が不適切です。" End Sub これで、同名のエラーや文字数超過、不適切な文字列の使用を排除できます。
補足
ありがとうございます。 同名のエラーや文字数の超過など個別に チェックする方法は難しいのでしょうか?
関連するQ&A
- シート番号追加VBA
watabe007さま 大変お世話になりました 前にシートのセルにページ番号を追加するVBAをこちらで教えて頂きまして、本当に有難うございます 前回に下記の内容を教えて頂き、大変有難く使わせていただいております Sub pageA() Dim i As Long For i = 1 To Worksheets.Count If Worksheets(i).Name = "Sheet3" Then Worksheets(i).Range("G2") = "'" & i & "/" & Worksheets.Count ElseIf Worksheets(i).Name = "Sheet4" Then Worksheets(i).Range("G3") = "'" & i & "/" & Worksheets.Count Else Worksheets(i).Range("G1") = "'" & i & "/" & Worksheets.Count End If Next End Sub それで、今回はどのシート名にも属さないシートはページカウントとしてカウントしない、という方法がありましたらお教え頂きたいのですが、方法はありますでしょうか? お忙しいかと思いますが、アドバイス頂けますますと嬉しいです
- ベストアンサー
- Excel(エクセル)
- エクセルVBAでSheet1.ActivateとSheet(n).Activate
エクセル2000です。 VBAでの疑問点を教えてください。 Sub test1() Sheet1.Activate MsgBox ActiveSheet.Name End Sub これは問題なく作動します。 Sub test2() x = ThisWorkbook.Worksheets.Count For n = 1 To x Sheet(n).Activate MsgBox ActiveSheet.Name Next End Sub これは「SubまたはFunctionがていぎされていません」というエラーになります。 もちろん、 Sub test3() x = ThisWorkbook.Worksheets.Count For n = 1 To x Sheets(n).Activate MsgBox ActiveSheet.Name Next End Sub のように書けばOKなのは存じておりますが、これではSheet名に係らず、左から順番となってしまいます。 Sub test4() x = ThisWorkbook.Worksheets.Count For n = 1 To x Sheets("Sheet" & n).Activate MsgBox ActiveSheet.Name Next End Sub のように明確にシート名として記述すればOKなのですが、それでは、Test1のSheet1.Activate が通って、Sheet(n).Activate が通らないのはなぜでしょう? しょうもない質問でごめんさない。
- ベストアンサー
- オフィス系ソフト
- Excel VBAである特定文字列を含むシート名例えば「りんご(1)」
Excel VBAである特定文字列を含むシート名例えば「りんご(1)」「みかん(1)」「みかん(2)」「いちご(1)」のシート名があるファイルに対して「みかん*」で検索を行い、一致したシート(複数Sheet)=「みかん(1)」「みかん(2)」に対して処理を行う方法はありますでしょうか。 宜しくお願いいたします。 完全一致するファイルは下記のようなのですが、Scheck = 0の部分が理解でいません。 型は何にすればよいのでしょうか。 Sub Sheet_Add5() Scheck = 0 For Each sheet_name In Worksheets If sheet_name.Name = ("検索シート名") Then Scheck = 1 Exit For End If Next If Scheck = 0 Then Sheets.Add.Name = "検索シート名" End If End Sub
- ベストアンサー
- オフィス系ソフト
- VBAで初歩的な質問ですシートのコピーについて
Sub SheetCopy() For i=1 to 31 WorkSheets.Add.Move after:=WorkSheets(workSheets.Count) シート名=i ActiveSheet.Name=シート名 Next End Sub と、シートをコピーするプロシージャを作りました。本当は、シート名を7月1日から、7月31日の31枚を作りたいのですが、どのように書けばよいのでしょうか? よろしくお願いします。
- ベストアンサー
- Visual Basic
- excel vba シートの取り扱い
Sub aaa() Worksheets.Add ActiveSheet.Name = "Namefile" ((質問)ここへ適当なコードを追加することによって 以下のThisWorkbook.Sheets(1)というのを、上で追加した Namefileシートを処理することとしたい。 つまり Namefileシート=ThisWorkbook.Sheets(1) どうすればいいか。よろしくお願いします。) ThisWorkbook.Sheets(1).UsedRange ThisWorkbook.Sheets(1).UsedRange.Delete ThisWorkbook.Sheets(1).Range("B2") = "ファイル名" ThisWorkbook.Sheets(1).Range("C2") = "最終更新日" End Sub
- ベストアンサー
- オフィス系ソフト
- vba エクセルシートの追加、名前の変更について
エクセルvbaについて教えてください 新しいシートを一番右に作成し、その新規作成したシートの名前を変えたいです Sub Sample() Worksheets.Add after:=Worksheets(Worksheets.Count) ActiveSheet.Name = "結果1" End Sub と作成しました マクロを実行したら、「結果1」という名のシートが一番右に作成されます その後、実行をしたら「結果2」、さらに実行したら「結果3」といった感じにどんどん「結果+数字」のシートを作成したのですが、今のままでは「結果1」というシートしか作成されません 「結果2」、「結果3」、・・・・エンドレスに作成するようにするにはどうしたらよいのでしょうか ―――――――――――――――――――――――――――――――――――― なぜこのようなことをしているかといいますと、AdvancedFilterでxlFilterCopyを利用し、抽出した結果を新しいシートに作成するようにするのが最終目標です それで、まずAdvancedFilterでデータを反映させる新しいシートを作成することに取り組んでいるところです もし分かる方がいましたら、AdvancedFilterでxlFilterCopyする際、上で説明しました新しいシートが作成できた場合、CopyToRangeをどのように記載すればいいのか分かればそれも教えていただけると助かります よろしくお願いします
- ベストアンサー
- その他MS Office製品
- VBA シート名重複した場合削除する
教えてください。 VBAに関しての質問です。 全くの知識がないので教えていただきたいです。 エクセルワークシートに以下の機能を追加している状態です。 For Each ws In Worksheets If ws.Name = "データ" Then wsChkflg = True End If Next If wsChkflg = True Then ThisWorkbook.Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = "データ" Else ThisWorkbook.Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = "データ" End If Set wsNew = ThisWorkbook.Worksheets("データ") 「データ」というシートが作成、追加されるのですが、同じシート名で新規作成した時に エラーが出てしまいます。そのエラーを出さないようにすため、ダイアログ等も出さずに既存のシートを強制的に削除する機能を追加したいのです。 VBAの知識がなくて困っています。 何か良い方法がわかる方いらっしゃいましたらお力を貸してください。 よろしくお願いいたします。
- ベストアンサー
- オフィス系ソフト
- エクセルVBA シート名の部分一致検索について エクセル2007
VBAでエクセルの全シート名を部分一致で検索したいと考えています。 そこで以下のコードを書いたのですが、 インプットボックスにどんな文字列を入力しても全てのシート名を 取得してしまって途方にくれています。 どなたかお助けください。 Sub test01() Dim name As String Dim ws As Worksheet shn = InputBox("検索文字列を入力") For Each ws In ThisWorkbook.Worksheets If ws.Name Like " * " & name & " * " Then ws.Activate MsgBox ws.Name End If Next ws End Sub
- 締切済み
- オフィス系ソフト
- Excel VBAシートの同一番地のセルのリスト化
別々のシートの同一番地のセルの値をリスト化するのにこのようなVBAを見つけました。 シートは追加せず、既存のシートを指定したくて、色々と書き換えをチャレンジしましたがうまくいきません。 既存のシートを指定し、この作業を行うにはどうしたらよいのでしょうか? ご教示いただけますと幸甚です。 Sub Test1() Dim TmpSheet As Worksheet, i As Integer i = Worksheets.Count Set TmpSheet = Worksheets.Add(After:=Sheets(Sheets.Count)) With TmpSheet For i = 1 To i .Cells(i, 1).Value = Worksheets(i).Name .Cells(i, 2).Value = Worksheets(i).Range("E5").Value Next End With End Sub
- ベストアンサー
- Excel(エクセル)
- EXCEL VBAにてのワークシート作成
エクセルのVBAにてワークシートを作成することで困っています。 自分で書き込んだのは Private Sub CommandButton1_Click() Worksheets("原紙").Copy ActiveSheet.Name = TextBox1 Worksheets.Add After:=Worksheets(2) End Sub Private Sub UserForm_Initialize() TextBox1 = Format(Date, "yy.mm.dd") End Sub 実行したいことはCommandButton1クリック時に 左から2番目にあるワークシート 原紙を テキストボックス1に入力されている(日付) 名前を付けて左から3番目に新規で作成したいのですが 思うように動かずエラーが出てしまいます。 どの様に修正すれば宜しいでしょうか? またクリック時にすでにテキストボックス1と同じ 名前のワークシートが存在した場合はそのワークシートを Activeにしたいのですがどの様に書き込めば宜しいでしょうか? 重ね重ねですが宜しくお願いいたします。
- ベストアンサー
- オフィス系ソフト
お礼
ありがとうございます お手数をおかけ致しました。 出来ました!! 感謝です。 何から何まで本当にありがとうございました。