For~Nextルーチンで最初の1回しか処理してくれません(Excelマクロ)

このQ&Aのポイント
  • ExcelのFor~Nextルーチンで処理が正常に行われない問題について質問させていただきます。
  • 質問内容は、セルのデータをリストボックスに表示し、ユーザーが選択した項目を含む行を削除するマクロに関するものです。
  • 現在の問題は、選択した項目のうち最初のものだけが削除され、それ以降の項目が処理されないという点です。
回答を見る
  • ベストアンサー

For~Nextルーチンで最初の1回しか処理してくれません(Excelマクロ)

ご覧いただきありがとうございます。 Excelで下記のようなマクロを書いたのですが、思ったような処理をしてくれません。色々なWebページや参考書に当たってみましたが、どうしてもわかりません。どの点が間違っているのか、どう直したらよいか、ご教示いただけませんでしょうか。 なお、意図している処理は次のようなものです。  ・セルB2:B21のデータをリストボックスに表示(この部分は別途作成済みです)  ・リストボックスに表示されている項目をユーザーが複数選択する  ・選択後コマンドボタン2をクリックすると、選択された項目を含む行を削除する 以上ですが、選択した項目のうち最初のものだけを削除しただけで終了しています。お手数をおかけいたしますが、よろしくお願いいたします。 Private Sub CommandButton2_Click() Application.ScreenUpdating = False Dim I As Integer If ListBox1.ListIndex = -1 Then MsgBox "選択されていません" Exit Sub End If Dim myStr(19) As Variant Dim myCell(19) As Variant With ListBox1 For i = 0 To .ListCount - 1 If .Selected(i) Then MsgBox .List(i) myStr(i) = .List(i) Set myCell(i) = Workbooks("PERSONAL.XLS").Sheets(1).Range("B2:B21").Find(myStr(I), , xlValues, xlWhole) ThisWorkbook.Activate myCell(i).EntireRow.Delete End If Next i End With Unload Me Application.ScreenUpdating = True End Sub

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

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.12

お約束のコードです。標準モジュール部 Public myApp As Class1 Public LatestFileName As String 'Class からの出力 Public MyFileName As String Private WinState As Integer Private ClearFlg As Boolean Private Const LIMIT_NUM As Integer = 10 '0:デフォルト,1:ユーザー選択モード,その他:完全固定モード Public Const FIXEDMODE As Integer = 0 Sub Auto_Open() Call SetMyApp End Sub Sub SetMyApp() '起動時のApplicationインスタンス StartFlg = True Set myApp = New Class1 Set myApp.App = Application On Error Resume Next If CommandBars("WorkSheet Menu Bar").Controls("ファイルリスト(&L)").Tag = "" Then Call CommandMenu_Add End If End Sub Sub CommandMenu_Add() 'メニューの作成 Dim myCB As CommandBar Dim MyCBCtrl As CommandBarControl Dim myBtn As CommandBarButton Dim CBBox1 As CommandBarComboBox Dim CBBox2 As CommandBarComboBox Dim cnt As Integer Set myCB = Application.CommandBars("WorkSheet Menu Bar") cnt = myCB.Controls.Count 'ファイルリスト親メニュー Set MyCBCtrl = myCB.Controls.Add(Type:=msoControlPopup, _ Before:=cnt + 1, Temporary:=False) With MyCBCtrl .Caption = "ファイルリスト(&L)" .Tag = "FL" 'ファイルリストボックス Set CBBox1 = myCB.Controls("ファイルリスト(&L)").Controls.Add( _ Type:=msoControlDropdown, _ Temporary:=False) With CBBox1 .DropDownWidth = 120 'これら以外は設定できない .DropDownLines = LIMIT_NUM '行数 .OnAction = "MyFNOpen" .Visible = True .Tag = "CB1" '検索のためのタグ設定 End With 'データをストックするコンボボックス Set CBBox2 = myCB.Controls("ファイルリスト(&L)").Controls.Add( _ Type:=msoControlComboBox, _ Temporary:=False) With CBBox2 .Tag = "CB2" '検索のためのタグ .Caption = "CB2" .Visible = False End With 'リストの消去メニュー With myCB.Controls("ファイルリスト(&L)").Controls.Add( _ Type:=msoControlButton, _ Temporary:=False) .Caption = "リストの編集(&E)" .OnAction = "ListEdit" .FaceId = 31 End With 'リストの消去メニュー With myCB.Controls("ファイルリスト(&L)").Controls.Add( _ Type:=msoControlButton, _ Temporary:=False) .Caption = "リストの編集終了(&T)" .OnAction = "ListComplete" .BeginGroup = False .FaceId = 11 End With 'リストの消去メニュー With myCB.Controls("ファイルリスト(&L)").Controls.Add( _ Type:=msoControlButton, _ Temporary:=False) .Caption = "リストの全消去(&C)" .OnAction = "ListClear" .BeginGroup = False .FaceId = 67 End With 'リストの消去メニュー With myCB.Controls("ファイルリスト(&L)").Controls.Add( _ Type:=msoControlButton, _ Temporary:=False) .Caption = "メニューの消去(&M)" .OnAction = "MenuDelete" .BeginGroup = False .FaceId = 459 End With End With Set MyCBCtrl = Nothing Set myCB = Nothing End Sub Sub ListClear() 'リストの内容の消去 With CommandBars.FindControl(, , "CB1") If .ListCount = 0 Then Exit Sub If MsgBox("リストをすべて消してよろしいですか?", vbOKCancel) = vbCancel Then Exit Sub Else .Clear End If End With With CommandBars.FindControl(, , "CB2") .Clear End With End Sub Sub CommandMenu_Delete() 'メニューの削除(単独の予備マクロ) On Error Resume Next With Application.CommandBars("WorkSheet Menu Bar") .Controls("ファイルリスト(&L)").Delete End With On Error GoTo 0 End Sub Sub Item_Add(LatestFileName As String) Dim i As Integer Dim n As Integer Dim Arbuf() As String Dim iMax As Integer Dim CBBox1 As CommandBarComboBox Dim CBBox2 As CommandBarComboBox Set CBBox1 = CommandBars.FindControl(, , "CB1") Set CBBox2 = CommandBars.FindControl(, , "CB2") If CBBox1 Is Nothing Then Exit Sub If CBBox2 Is Nothing Then Exit Sub n = FindItem(LatestFileName) If CBBox2.ListCount = 0 Then CBBox2.AddItem LatestFileName CBBox1.AddItem Full2FName(LatestFileName) Exit Sub End If While (FindItem(LatestFileName) > 0) n = FindItem(LatestFileName) CBBox2.RemoveItem n Wend If CBBox2.ListCount >= LIMIT_NUM - 1 Then iMax = LIMIT_NUM - 1 Else iMax = CBBox2.ListCount End If ReDim Arbuf(iMax) '添え字0があるのでひとつ増える For i = 1 To iMax If CBBox2.ListCount >= i Then If CBBox2.List(i) <> "" Then Arbuf(i) = CBBox2.List(i) End If End If Next Arbuf(0) = LatestFileName CBBox1.Clear CBBox2.Clear For i = 0 To iMax If Arbuf(i) <> "" Then CBBox1.AddItem Full2FName(Arbuf(i)) CBBox2.AddItem Arbuf(i) End If Next LatestFileName = "" End Sub Sub Item_AddOpt(LatestFileName As String) 'ユーザー選択用 Dim i As Integer Dim j As Integer Dim n As Integer Dim k As Integer Dim Arbuf() As String Dim Arstock() As String Dim iMax As Integer Dim CBBox1 As CommandBarComboBox Dim CBBox2 As CommandBarComboBox Dim strTop As String Set CBBox1 = CommandBars.FindControl(, , "CB1") Set CBBox2 = CommandBars.FindControl(, , "CB2") If CBBox1 Is Nothing Then Exit Sub 'エラー処理 If CBBox2 Is Nothing Then Exit Sub n = FindItem(LatestFileName) If CBBox2.ListCount = 0 Then CBBox2.AddItem LatestFileName CBBox1.AddItem Full2FName(LatestFileName) Exit Sub End If While (FindItem(LatestFileName) > 0) n = FindItem(LatestFileName) CBBox2.RemoveItem n Wend For i = 1 To CBBox1.ListCount If Left(CBBox1.List(i), 1) Like "[#&$]" Then '特別な印 ReDim Preserve Arstock(1, k) On Error Resume Next Arstock(1, k) = CBBox2.List(i) Arstock(0, k) = CBBox1.List(i) CBBox2.List(i) = "" On Error GoTo 0 k = k + 1 '固定ファイル名ストック If strTop = "" Then strTop = Left$(CBBox1.List(i), 1) End If Next i If CBBox2.ListCount >= LIMIT_NUM - 1 Then iMax = LIMIT_NUM - 1 - k Else iMax = CBBox2.ListCount - k End If ReDim Arbuf(iMax) '添え字0があるのでひとつ増える For i = 1 To iMax If CBBox2.ListCount >= i Then If CBBox2.List(i) <> "" And Not (CBBox1.List(i) Like "[#&$]") Then Arbuf(i) = CBBox2.List(i) End If End If Next If LatestFileName <> "" Then Arbuf(0) = LatestFileName End If CBBox1.Clear CBBox2.Clear For i = 0 To iMax If Arbuf(i) <> "" Then CBBox1.AddItem Full2FName(Arbuf(i)) CBBox2.AddItem Arbuf(i) End If Next If k > 0 Then For j = 0 To UBound(Arstock(), 2) If Arstock(1, j) <> "" Then CBBox2.AddItem Arstock(1, j) CBBox1.AddItem Arstock(0, j) End If Next End If LatestFileName = "" End Sub Private Sub MyFNOpen() 'コマンドメニューリストの選択によって開かれる Dim CBBox1 As CommandBarComboBox Dim CBBox2 As CommandBarComboBox Dim ng As Boolean 'ファイルがない場合 Dim i As Integer Set CBBox1 = CommandBars.FindControl(, , "CB1") Set CBBox2 = CommandBars.FindControl(, , "CB2") With CBBox1 i = .ListIndex If CBBox2.List(i) <> "" Then sFNOpen CBBox1.List(i), ng 'ファイルオープン If ng Then CBBox1.List(i) = "*" & CBBox1.List(i) CBBox2.List(i) = "" End If End If .ListIndex = 0 End With End Sub Private Sub sFNOpen(fn As String, ng As Boolean) Dim Wb As Variant 'ファイルを開けるサブルーチン On Error GoTo EndLine For Each Wb In Workbooks If Wb.Name Like fn Then Wb.Activate Exit Sub End If Next Wb ng = False If Len(Dir(fn)) > 0 Then Workbooks.Open (fn) Else ng = True End If EndLine: On Error GoTo 0 End Sub Sub ListEdit() '新規ファイルリストブック作成 Dim MyFile As Workbook Dim Sh As Worksheet Dim DefShCnt As Integer 'DefaultSheetCount Dim CBBox1 As CommandBarComboBox Dim CBBox2 As CommandBarComboBox Dim WinState As Integer Dim i As Integer DefShCnt = Application.SheetsInNewWorkbook Application.SheetsInNewWorkbook = 1 Set MyFile = Workbooks.Add If Len(Dir(MyFile.FullName)) > 0 Then If MsgBox("バックアップログが残っています。使用しますか?", vbOKCancel) = vbOK Then GoTo EndLine End If End If Application.SheetsInNewWorkbook = DefShCnt WinState = ActiveWindow.WindowState With MyFile.Windows(1) .WindowState = xlNormal .Width = 200 .Height = 450 'ウィンドウの高さ '.Caption = "リストの再編成" .DisplayHeadings = False .DisplayHorizontalScrollBar = False .DisplayVerticalScrollBar = False .DisplayWorkbookTabs = False .ActiveSheet.Columns(1).ColumnWidth = 8 .ActiveSheet.Columns(2).ColumnWidth = 45 .ActiveSheet.Rows("1:40").RowHeight = 15 End With If ClearFlg = False Then Application.Caption = "" Application.Caption = "リスト編集中" End If Set Sh = MyFile.ActiveSheet MyFile.Protect Windows:=True Sh.ScrollArea = "A1:C100" 'スクロールロック For i = 1 To LIMIT_NUM With Sh.OLEObjects.Add( _ ClassType:="Forms.CheckBox.1", _ Link:=False, _ Left:=Sh.Cells(i, 1).Left + 15, _ Top:=Sh.Cells(i, 1).Top + 1, _ Width:=Sh.Cells(i, 1).Width * 2 / 3, _ Height:=Sh.Cells(i, 1).Height _ ) .Visible = True .Object.Caption = "" End With Next i Sh.Cells(i + 2, 2).Value = "不要なものはチェック" Sh.Cells(i + 3, 2).Value = "オフにしてください" Sh.Cells(i + 4, 2).Value = "リスト編集終了で" Sh.Cells(i + 5, 2).Value = "終了してください。" Set CBBox1 = CommandBars.FindControl(, , "CB1") Set CBBox2 = CommandBars.FindControl(, , "CB2") For i = 1 To CBBox1.ListCount If i <= LIMIT_NUM Then Sh.Cells(i, 2).Value = CBBox1.List(i) Sh.Cells(i, 4).Value = CBBox2.List(i) Sh.OLEObjects("CheckBox" & i).Object.Value = True End If Next Application.DisplayAlerts = False MyFile.SaveAs "MyFileList" If ClearFlg = True Then MyFile.Close False End If Application.DisplayAlerts = True Set Sh = Nothing EndLine: Set MyFile = Nothing End Sub Sub ListComplete() 'リストの終了時 Dim MyFile As Workbook Dim Sh As Worksheet Dim CBBox1 As CommandBarComboBox Dim CBBox2 As CommandBarComboBox Dim buf1() As String Dim buf2() As String Dim i As Integer Dim j As Integer Dim e As Integer Dim n As Integer On Error GoTo ErrHandler Set MyFile = Workbooks("MyFileList.xls") MyFileName = MyFile.FullName Set Sh = MyFile.Sheets(1) With Sh For i = 1 To LIMIT_NUM If .OLEObjects("CheckBox" & i).Object.Value = True Then 'データがあっても、行がなければ最終的には取り込まれない ReDim Preserve buf1(j) ReDim Preserve buf2(j) buf1(j) = Sh.Cells(i, 2).Value buf2(j) = Sh.Cells(i, 4).Value j = j + 1 End If Next i End With Set CBBox1 = CommandBars.FindControl(, , "CB1") Set CBBox2 = CommandBars.FindControl(, , "CB2") CBBox1.Clear CBBox2.Clear On Error Resume Next i = UBound(buf1) If Err.Number = 0 Then For j = LBound(buf1) To UBound(buf1) If Err.Number = 0 Then CBBox1.AddItem buf1(j) CBBox2.AddItem buf2(j) End If Next j End If Application.Caption = "" Application.EnableEvents = False MyFile.Close False Application.EnableEvents = True Kill MyFileName Set Sh = Nothing Set MyFile = Nothing If WinState <> 0 Then ActiveWindow.WindowState = WinState End If ErrHandler: If Err.Number <> 9 And Err.Number > 0 Then '9は、ブックがない MsgBox Err.Description End If End Sub Sub MenuDelete() Dim myMenu As CommandBarControl 'Menuの消去 On Error Resume Next Set myMenu = CommandBars("WorkSheet Menu Bar").Controls("ファイルリスト(&L)") If Not myMenu Is Nothing Then If MsgBox("メニューを消去するとリストもなくります。" & vbCrLf & _ "よろしいですか?", vbOKCancel) = vbOK Then Application.ScreenUpdating = False ClearFlg = True Call ListEdit Application.ScreenUpdating = True myMenu.Delete End If End If On Error GoTo 0 End Sub '===========ユーザー定義関数=============================== Function FindItem(fn As String) As Integer Dim flg As Boolean Dim CBBox2 As CommandBarComboBox Set CBBox2 = CommandBars.FindControl(, , "CB2") If CBBox2 Is Nothing Then Exit Function For i = 1 To CBBox2.ListCount If StrComp(fn, CBBox2.List(i), 1) = 0 Then Exit For End If Next i If CBBox2.ListCount < i Then i = 0 End If FindItem = i End Function Function Full2FName(fn As String) Dim buf As String k = InStrRev(fn, "\") If k > 0 Then buf = Mid$(fn, k + 1) Else buf = fn End If Full2FName = buf End Function

その他の回答 (20)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.10

Wendy02です。 もう一度、最初からやり直しの決定をしました。理由は二つあって、データの出し入れで、データがなくなるのです。(たぶん、UserFormでも行っても同様のトラブルの発生の可能性はあります) また、イベントの最中に不安定になることに気がつきました。早い話が、個人用マクロブックでも、どこでも同じなのですが、ブックを開く時、閉じる時に、一番加重が掛かるのです。一部のブックのBeforeClose イベントで、開いている部分のモジュールのタイプが、すげ変わってしまうという、致命的なバグがあり解消できません。単に、それを避けるだけなら、エラー・トラップを設ければよいのですが、それは、結果的、どこかでまたエラーが発生する原因になります。私が、「個人用マクロブック」の難しさを書いていた、ひとつなのだと思います。 今までのUserForm の方法でも良いので、それに切り替えようか、昨日夜迷いましたが、今の方針自体は間違っていないと思いなおし、もう少し続けてみようと思います。 そういう私も、この機にExcelというものを勉強しなおしているようなものです。(掲示板で公開してしまったら、何だそんなことかで、おしまいですが、)やはり新しいテクニックを開発しているわけです。小手先のテクニックではどうしようもなく、自分の開発経験の浅さに嘆きつつも、もう少しがんばってみます。お時間掛けてすみません。

akeem2003
質問者

お礼

こんばんは。お世話になります。 No.9でお示しいただいたコードについて、それぞれの命令文がどのような意味を持っているのか、Webで調べたりしています。まだまだわからない部分も多いのですが、とても勉強になります。 わたしなどには到底想像もできないようなハイレベルなマクロをお考えくださっていることと思います。 >お時間掛けてすみません。 とんでもないです。わたしのほうこそなにもできずに申し訳ありません。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.9

こんばんは。Wendy02です。 最初に作ったものは、ボツにしましたので、本日、別な方法でつくり、やっと、今、9割できたようですが、しばらく使って、バグを探している最中です。何年ぶりかで、本格的なものを作ったのです。 しかし、ここの書き込み時に注意がありますが、 #回答は全角800字(半角1600字)以内です。これを超える長文の分割投稿はご遠慮ください。 ここに掲示するためには、そのローカルルールに触れるような気がします。行数で、500行ぐらいになってしまいます。半角文字数換算で、8,000字 ぐらいになってしまうようです。私は、ここのローカルルールに触れそうになるのは、初めてなのです。 本来は、直接、お渡しする内容のようです。 ちょっと、困ってしまいました。やってみるしかありませんね。しょうがありません。 結局、別のブックを使用して書き込みすることにしましたが、いろいろ試してみて、ブックの使用中は、書き込みをしないようにしました。そして、メモリ上にデータを置くのはやめて、必ず、隠しコンボボックス内のリストに置くという方法を立てました。これは、隠し技のひとつになると思います。(EXCELのメモリは不安定で失いやすいからです) 以下が、見える側のコンボボックスです。    Set MyCB = Application.CommandBars("WorkSheet Menu Bar")    cnt = MyCB.Controls.Count   'ファイルリスト親メニュー  Set MyCBCtrl = MyCB.Controls.Add(Type:=msoControlPopup, _       Before:=cnt + 1, Temporary:=True)       With MyCBCtrl   .Caption = "ファイルリスト(&L)"   .Tag = "FL"  End With 小出しにするつもりではないのですが、前書きとして、大事な部分を書いておきます。 '----------------------------------------- 'Class1 設定 Private WithEvents NewApp As Application Public Property Set App(ByVal myApp As Application) 'カプセル化  Set NewApp = myApp End Property Private Sub NewApp_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean) If ThisWorkbook.Name <> Wb.Name And _   Not (Wb.Name Like "Book#*") And _   Wb.IsAddin = False And _   StrComp(Wb.Name, INI_FILE, vbBinaryCompare) Then  LatestFileName = Wb.FullName  Call Item_Add(LatestFileName) ElseIf StrComp(Wb.Name, INI_FILE, vbBinaryCompare) = 0 And StartFlg = False Then  Call MakingFileNameLists End If End Sub '--------------------------------------------- '標準モジュール Public myApp As Class1 Public LatestFileName As String 'Class からの出力 Public StartFlg As Boolean Sub Auto_Open()  '起動時の自動実行  Call SetMyApp End Sub Sub SetMyApp() '起動時のApplicationインスタンス  StartFlg = True  Set myApp = New Class1  Set myApp.App = Application   End Sub このコードは、ファイルを終了したときに、ファイルの名前が、出力されるためのイベントです。変数の LatesFileName が出力されます。なお、一部変更する可能性があるのは、StartFlg のブーリアン値を逆にするかもしれません。(以上約1750字)

akeem2003
質問者

補足

Wendy02さん お世話になりましてありがとうございます。 >私は、ここのローカルルールに触れそうになるのは、初めてなのです。 わたしのせいでご迷惑をおかけしまして申し訳ありません。大変な労力を割いていただき、本当になんとお礼を申し上げたらよいかわかりません。 それから、ご報告ですが、No.6でお教えいただいたコードを職場で試してみたところ、Wendy02さんが予想されたとおり、リストを表示してくれませんでした。 わたしがいうのもヘンですが、あまり根を詰めていただいてお体に障るようなことのないよう、お気をつけください。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.8

こんばんは。 最初に、まだ、マクロは出来そうにもありません。 あまり、複雑なものを考えすぎたのかもしれません。「PERSONAL.XLS」に書き込まないで、ログを取ることは、問題はないのですが、そのファイル名の保存とリストとの表示のタイミングが、今、見えてこないのです。たぶん、保存するときが、本来、ベストではないかとは考えて作っているのですが、まだ、書き終わっていないのです。かなりコードが、長文になってしまいました。こういうケースは、いままでなかったのです。今のようなペースだと、だいたい、失敗のケースが多いです。 ただ、今回の事情を聞かせていただき、これは何とかしなくてはいけない、と思いました。中途半端なものではいけないですね。もしかしたら、アドインのほうが良いかもしれません。個人の問題ではないのではないのでしょうから。 >管理者にもきいたのですが、全社的にわざわざそういう設定にしてあるとのことでした(ファイル履歴が使えるとセキュリティ的にどんな不都合があるのかは、面倒だったのか、それとも秘密なのか、説明してもらえませんでしたが)。 自分と会社との立場の関係があるから、それは簡単にはいかないでしょうけれども、akeem2003さんが今おやりになっているような、VBAを動かすことが許可されているなら、はっきり言えば、何とかなります。会社によっては、VBA禁止令が出ているところもありますから。 また、C:\File Programes/C:\Windows フォルダの書き込み、閲覧禁止というところはあります。もしかしたら、IE を殺してあるとか?単に、Office の履歴だけを取れないようにする意味はないので、他の複合的な問題かもしれません。 私は、前回に書いた、「PERSONAL.XLS」に書き込みをしないという原則も、撤回したほうがよいかもしれません。もう、背に腹は変えられないというか。 (事情が分からなかったので、一方的な言い分を書いて、大変申し訳ありません。年に1度のトラブルもないものに、あれこれ言っても、履歴を見れないほうが遥かに問題は大きいです!)いろいろ、思考錯誤してみます。

akeem2003
質問者

補足

Wendy02さま 大変お手数をおかけしまして申し訳ありません。ここまで親身になっていただいて、本当にありがたく思っております。おおげさではなく、感激で涙が出そうです。 >C:\File Programes/C:\Windows フォルダの書き込み、閲覧禁止というところはあります。もしかしたら、IE を殺してあるとか? 確かに、c:ドライブは一般ユーザーには閲覧すら許可されていません。IEは、セキュリティ関係の設定をいじれないようにはされていますが、使用はできます。 面倒なことにおつきあいいただき申し訳ありませんが、なにとぞよろしくお願い申し上げます。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.7

こんにちは。 >Excelの ツール-オプション-最近使用したファイルの一覧 というメニューも、グレーになっていて操作できないようにされています。 >何やらセキュリティの関係だとかで、エクスプローラーやオフィスソフトのファイル履歴が表示されないのです。 それは、かなり使いづらいですね。実は、その「グレー」になって操作できない現象が、PERSONAL.XLS か、EXCEL.XLB ファイルの反乱を起こして、「グレー」になることがあるのです。その二つのファイルを削除すると、デフォルトに戻ると同時に、機能は復活するはずなのですが。(PERSONAL.XLS のマクロは、一旦、エクスポートして、新たに作ったPERSONAL.XLS にインポートします) 本当に、「設定されたもの?」か、管理者さんに確認されたほうがよいのではありませんか?エクスプローラはともかくとして、Excelでは、トラブル以外は、そんな話は聞いたことがありません。 それから、私の書いたマクロは、そういう状態では使えないはずです。以前も、似たような相談を受けてだめだった経験があります。 今は、ファイル名は、手書きか何かをされているわけですね。 ファイル名のログを取るマクロというのは、今すぐ出来ませんが、ある程度のイメージはあります。そういう種類のマクロは、半端じゃなく、難しそうです。しばらく考えて、もし、だめだったら、ダメだったという書き込みを入れます。 順を追って、リストのファイル名が下に追いやられるように作らなくてはならないことですね。手動で削除する方法も入れておかなくてはなりません。

akeem2003
質問者

補足

こんにちは、大変お世話になりましてありがとうございます。 >本当に、「設定されたもの?」か、管理者さんに確認されたほうがよいのではありませんか? 管理者にもきいたのですが、全社的にわざわざそういう設定にしてあるとのことでした(ファイル履歴が使えるとセキュリティ的にどんな不都合があるのかは、面倒だったのか、それとも秘密なのか、説明してもらえませんでしたが)。同僚達もあきらめて使っています。(;_;) ファイルの場所は記憶に頼っていますが、さっき使ったファイルでも、上司から急に「○○の資料すぐ出して」などといわれて慌てると、全然わからなくなったりします。 >そういう種類のマクロは、半端じゃなく、難しそうです。 まさかそんなこととは予想もせず、わたしは無謀な挑戦をしていたのですね。冷や汗ものです。 >しばらく考えて、もし、だめだったら、ダメだったという書き込みを入れます。 ご好意に甘えっぱなしでまことに恐縮ですが、なにとぞよろしくお願いいたします。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.6

#4の補足の回答をさせていただきます。 >気のせいか、処理速度が上がったように思います。 人の感知するレベルでの速度は上がっていないはずですが、RowSource の使い方は、少し、イレギュラーかもしれません。トラブルはないとはいえないのですが、アクセスが速いです。 >どこかのWebページで、「PERSONAL.XLSを記録用に使っている」 たぶん、あえて、サイトの場所は示しませんが、私の知っている有名な場所でしたら、そこの内容のレベルは、あまり高くありませんし、直す点がかなりあるようです。PERSONAL.XLS は、主に、Excelのツールボタンのマクロに登録するのが一般的です。 特に、あまりPERSONAL.XLS に詰め込みますと、起動時間が遅くなったり、ツール-オプションのデフォルト設定に影響を受けることがあったり、最悪は、起動しなくなったりします。年に1度あるトラブルでもありませんが、絶対にないトラブルとは言えないのです。理由は、XLSというバイナリ・ファイルの構造そのものに原因があります。 「最近使ったエクセルファイルを記録して、リストボックスで一覧表示し、リストから選んで再びそのファイルを開く」 ご質問のコードとご説明と内容が違うようですし、既存のメニュー-ファイルの中に、その機能はあるとは思います。 既存の機能の中で、 ○ツール-オプション-全般-最近使用したファイルの一覧  で、数を指定することが出来ますから、それで呼び出すだけでよいはずです。 >PERSONAL.XLSを使わない方法、まだちょっと思いつかないのですが、考え方のヒントだけでもお教えいただけないでしょうか。よろしくお願いいたします。 PERSONAL.XLS を使わないというよりも、出し入れを頻繁にしなければよいのです。Excel Applicationを終了したときに、変更の保存を催促されなければよいわけです。 参考までに、以下のような方法でもよいかと思います。イメージ的にはかなり違うかもしれませんが、PERSONAL.XLSには書き込みはしていません。既存の機能から呼び出しています。 ただ、本来は、こういうスタイルの場合、ツールバーやメニューバーに組み込んで、コンボボックス(CommandBarComboBox)にしたほうがよいです。少し、内容が高度になります。今は、便宜的に、UserFormにしてあります。(なお、二つのスタイルを作ってみて、これに決まりました。) なお、以下は、ListBox1 のMultiSelct 0-fmMultiSelectSingle になっています。ファイルを同時に開けることはありませんから。 Private Sub UserForm_Initialize() Dim myPath(20, 1) Dim i As Integer Dim j As Integer Dim buf As String On Error Resume Next Do While Err.Number = 0  Err.Clear  i = i + 1  j = InStrRev(Application.RecentFiles.Item(i).Name, "\")  If j > 0 Then   buf = Mid$(Application.RecentFiles.Item(i).Name, j + 1)  Else     buf = Application.RecentFiles.Item(i).Name  End If  myPath(i - 1, 0) = buf 'ファイル名  myPath(i - 1, 1) = Application.RecentFiles.Item(i).Path Loop ListBox1.List = myPath End Sub Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean) Dim wb As Variant Dim flg As Boolean Dim fName As String Dim i As Integer  flg = False  For Each wb In Workbooks   If ListBox1.Text = wb.Name Then    MsgBox "すでに" & ListBox1.BoundValue & "は開いています。": Exit Sub   End If  Next wb  On Error GoTo ErrHandler  For i = 0 To ListBox1.ListCount - 1   If ListBox1.Selected(i) = True Then    fName = ListBox1.List(i, 1)    'ファイルを開く    Workbooks.Open fName   End If  Next i Exit Sub ErrHandler:  MsgBox Err.Number & " :" & Err.Description End Sub p.s.私も別のプログラミングの初歩の初歩を勉強していますが、分からないことは、先回しです。先に行けば必ず分かるようになるというのが、VBAを学んだ経験から確信が得られました。1年後かもしれないし、2年後かもしれません。人間は、知らないことは、どうしても知りたいという本能もありますが、それをじっとこらえることも大事かなって思います。(^^;

akeem2003
質問者

補足

素晴らしいコードをお考えいただき本当にありがとうございます。1行ずつ読み解いて勉強させていただきます。そのうち、CommandBarComboBoxを使った処理にも挑戦したいと思います。 >ご質問のコードとご説明と内容が違うようです おっしゃるとおりです。改めて読み返すと、説明になっていませんでした。はじめに書いた「最近使ったエクセルファイルを記録して、リストボックスで一覧表示し、リストから選んで再びそのファイルを開く」の他に、「リスト中不要なファイル名は削除する」ということも考えておりまして、書き込んだコードは、後者の処理のためのものでした。訳のわからないことを書きまして失礼いたしました。 >既存のメニュー-ファイルの中に、その機能はあるとは思います。 私がこのマクロを使いたいと思っているのが、職場のパソコン上においてなのですが、何やらセキュリティの関係だとかで、エクスプローラーやオフィスソフトのファイル履歴が表示されないのです。Excelの ツール-オプション-最近使用したファイルの一覧 というメニューも、グレーになっていて操作できないようにされています。 忙しいときには、昨日(あるいはついさっき)使ったファイルの所在をいちいち探す作業にストレスを感じてしまいますので、なんとか自力で代替の機能を用意できないかと試しているところなのです。No.6でお示しいただいたコードが自宅のExcelと同様に職場でも動くかどうか、確認したいと思います。(うまくいけば最高なのですが…) それにしても、PERSONAL.XLS を不用意に操作することでExcelが起動しなくなることがあるとは思いもよりませんでした。これからは気をつけます。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.5

>数あるExcelマクロ書籍の中で、基本から今回お教えいただいたようなTipsまで #4 の私から、お勧めするのは、大村あつし氏の『かんたんプログラミングシリーズのExcel VBA』(3部)がよろしいと思います。全体的には、細かすぎる傾向があるのと、基礎編が概念的というか、大村氏独特の解釈の仕方は、ある程度、知っているものには、鼻に付くものであり、また、初心者には理解しにくいものがあるかと思います。そういう部分は、無視して良いと思います。しょせん、そんなことは、一回では覚えるわけではありませんし、後々になれば分かります。あまり根をつめて読まなければよいと思います。体系的というよりも、段階的に覚えていくのがよいです。今回の内容は、主に、2部のコントロール編で済みます。3部の応用編の技術は必要ないです。 とにかく、手を動かすこと。入力すること。プロシージャを最低でも500個ぐらい作って、「実行」すれば覚えられます。 本来は、純粋に、VBAから入ると良いのですが、そうすると、独習者は、飽きてしまうような気がします。ただ、そのほうが学習スピードは早いはずです。

参考URL:
http://www.amazon.co.jp/exec/obidos/ASIN/4774120286/
akeem2003
質問者

お礼

Wendy02さん ご推薦ありがとうございます。とてもよさそうな本ですね。これできちんと勉強し直そうと思います。 >あまり根をつめて読まなければよいと思います。 はい。気楽に気長にやっていきます(^^)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

こんばんは。 全体的に、コードがヘンです。 データだけを書き入れるなら、少なくとも、myCell は、配列変数だから、その値は、数値か文字列だけです。それを、PERSONAL.XLSに書く必要性はないですね。数千個とか出なければ、最初から、配列関数で配列変数に入れればよいです。 ThisWorkbook.Activate が、PERSONAL.XLS でないことを信じたいのですが、PERSONAL.XLS を書いたり消したりするのは、誤動作に元になりますから、絶対に、やめたほうがよいです。PERSONAL.XLS は、非表示シートですから、普段、書き入れたり、削除したりはしないようにします。 RowSource をPERSONAL.XLSから取っているのでしょうか? それを検索して、PERSONAL.XLSのRangeオブジェクトをとってもしょうがないと思います。 Set myCell(i) = そして、配列変数で宣言してあるのに、ここで、Rangeオブジェクトとして取っているわけです。エラーにはならないけれど、Rangeオブジェクト自体の情報は入らないはずです。 もし、Rangeオブジェクトにするなら、そこは、コレクション変数になるのですが、そんなワザが必要があるとも思えません。ひとつずつ消せばよいのですからね。 以下の場合は、Unionにしてあります。上から取っても、下から取っても、RowSource では、うまくいくとは思えないからです。 > ・セルB2:B21のデータをリストボックスに表示(この部分は別途作成済みです) だから、それを、Findメソッドで探すこともヘンです。 元のご質問の内容を全部読みきれてはいないのですが、参考までに書かせていただきました。以下は、直接、RowSource でとって、その範囲に対して、行の削除をするようになっています。リストの数が少ないから可能です。 なお、本来は、シートのSelect やActivate なりで、指定したほうが誤って行うことが少ないかとは思います。 '---------------------------------------------------- 'ListBox: MultiSelect = 1-fmMultiSelectMulti Private Sub UserForm_Initialize() 'セルB2:B21のデータをリストボックス   ListBox1.RowSource = Range("B2:B21").Address End Sub Private Sub CommandButton2_Click() Dim i As Integer Dim u As Range   Application.ScreenUpdating = False   If ListBox1.ListIndex = -1 Then     Exit Sub   End If      With ListBox1   For i = 0 To .ListCount - 1    If .Selected(i) = True Then     If u Is Nothing Then     Set u = Range("B2:B21").Cells(i + 1).EntireRow     Else     Set u = Union(u, Range("B2:B21").Cells(i + 1)).EntireRow     End If    End If   Next i   End With   If Not u Is Nothing Then     u.Delete   End If   Application.ScreenUpdating = True   Unload Me End Sub

参考URL:
 
akeem2003
質問者

補足

こんばんは。大変丁寧な解説とコードをお示しいただきまして、ありがとうございます。Wendy02さんのコードを試させていただきましたところ、気のせいか、処理速度が上がったように思います。きちんと書かれたコードの力というものでしょうか。 >ThisWorkbook.Activate が、PERSONAL.XLS でないことを信じたいのですが、 …実は、PERSONAL.XLS を使って、記録や削除を行っています。 そもそも全体的に何をしたいのかをきちんとご説明申し上げていませんでしたが、「最近使ったエクセルファイルを記録して、リストボックスで一覧表示し、リストから選んで再びそのファイルを開く」ということができるようにしようとしています。(Windowsの「最近使ったファイル」が使えないようにされていて、設定の変更もできないためです) 開いたファイル名をもれなく記録していくためには、常に一番最初に開かれるPERSONAL.XLSのThisWorkbookに、自動で起動するマクロを登録しておけばいいのではないかと考え、PERSONAL.XLSを利用することにした次第です。また、どこかのWebページで、「PERSONAL.XLSを記録用に使っている」という記述を見かけたため、そういう使い方もあるのだなと思い、PERSONAL.XLSに書き込みや削除を行っておりました。 >誤動作に元になりますから、絶対に、やめたほうがよいです。 よくわかりました。 PERSONAL.XLSを使わない方法、まだちょっと思いつかないのですが、考え方のヒントだけでもお教えいただけないでしょうか。よろしくお願いいたします。

noname#187541
noname#187541
回答No.3

No.2です。追加です。 行を削除するときは下から削除するのが基本です。 削除すると上に行が移動するので、行がずれて違う行が削除される音になります。 For i = .ListCount -1 To 0 Step -1 とした方がいいでしょう。

akeem2003
質問者

補足

>行を削除するときは下から削除するのが基本です。 恐れ入ります(^^; 色々な本やWeb上の情報を拾い読みしているような状態で、基本が身に付いておらず、恥ずかしい限りです。 ここは心を入れ替えて、きちんと体系的に勉強してみようと思います。それで、さらにお尋ねさせていただきたいのですが、数あるExcelマクロ書籍の中で、基本から今回お教えいただいたようなTipsまでを習得できるようなものをご存じないでしょうか。厚かましいお願いですが、お教えいただければ幸いです。

noname#187541
noname#187541
回答No.2

こんばんは。 ListBoxのList設定はRowSourceでやっていませんか? Listが再設定される(変わると選択が解除されます。 RowSourceでの設定だと、行を削除すると内容が変わるので選択が解除されます。 このために最初の1件しか削除されないのでしょう。 RowSourceをやめてAddItemで設定するといいでしょう。 ただし、Listはそのままなので設定し直す必要があります。

akeem2003
質問者

お礼

できました!完璧です!! ご指摘のとおり、 Private Sub UserForm_Initialize() UserForm1.ListBox1.RowSource = "B2:B21" … とRowSourceでList設定をしていました。その部分を Private Sub UserForm_Initialize() For i = 2 To 21 ListBox1.AddItem Cells(i, 2) Next i … と改め、さらに削除処理をするときのカウントの仕方を回答No.3で教えていただいたように直したところ、見事に望みどおりの動きをしてくれるようになりました。ここ数日悩んでいたことが嘘のように解決しました。本当にありがとうございました。

  • zap35
  • ベストアンサー率44% (1383/3079)
回答No.1

For i = 0 To .ListCount - 1 ListCountは1オリジン(1から始まる。0は項目がない状態)だったと思うのですが… For i = 1 To .ListCount にしたらどうなりますか?

akeem2003
質問者

補足

はじめまして。早速のご回答ありがとうございます。 For i = 1 To .ListCount にしてみたところ、例えばリストの上から1・3・5番目を選んでコマンドボタンをクリックすると、3番目に対応する行が削除され、2・4・6番目を選ぶと、2番目に対応する行が削除されるというように、2番目以降の最初の項目を含む行が削除されるようになりました。よろしくお願いいたします。

関連するQ&A

  • ListBox内の並び替えで実行エラー

    OSはXP、 Excelは2003を使用しています。 ユーザーフォーム内のListBox内で、コマンドボタンをクリックして行を上や下に並び替えたく、 http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1041407835 を参考にして、下記の通りに組んだのですが、 下に並び替えるCommandButton2を実行時や、 上に並び替えるCommandButton1を「2回目」に実行時に 「実行時エラー -2147417848(80010108)  オートメーションエラーです。 起動されたオブジェクトはクライアントから切断されました。」 となってしまいます。 Private Sub CommandButton1_Click() Dim i As Variant Dim j As Integer Dim k As Integer Dim myBuf1 As Variant Dim myBuf2 As Variant ' 選択されている項目を1つ上げる。 i = Me.ListBox1.ListIndex If i > 0 Then For j = 1 To 7 myBuf1 = Me.ListBox1.List(i - 1, j) Me.ListBox1.List(i - 1, j) = Me.ListBox1.List(i, j) Me.ListBox1.List(i, j) = myBuf1 Me.ListBox1.Selected(i - 1) = True For k = 0 To 6 myBuf2 = Me.ListBox2.List(i - 1, k) Me.ListBox2.List(i - 1, k) = Me.ListBox2.List(i, k) Me.ListBox2.List(i, k) = myBuf2 Me.ListBox2.Selected(i - 1) = True Next k Next j End If End Sub Private Sub CommandButton2_Click() Dim i As Variant Dim j As Integer Dim k As Integer Dim myBuf1 As Variant Dim myBuf2 As Variant ' 選択されている項目を1つ下げる。 i = Me.ListBox1.ListIndex If i < Me.ListBox1.ListCount - 1 Then For j = 1 To 7 myBuf1 = Me.ListBox1.List(i + 1, j) Me.ListBox1.List(i + 1, j) = Me.ListBox1.List(i, j) Me.ListBox1.List(i, j) = myBuf1 Me.ListBox1.Selected(i + 1) = True For k = 0 To 6 myBuf2 = Me.ListBox2.List(i + 1, k) Me.ListBox2.List(i + 1, k) = Me.ListBox2.List(i, k) Me.ListBox2.List(i, k) = myBuf2 Me.ListBox2.Selected(i + 1) = True Next k Next j End If End Sub 説明不足や上記の記述にとんちんかんな間違いがありましたら、ごめんなさい。 どなたか解決方法を教えて頂けますようお願い致します。

  • For~Nextについて

    VBA勉強中です。 For~Nextについて、いまいちわからないので、教えてほしいのですが、 下記の表を作り、テーブルと言う名前を付けました。 C列に上からA.Bの値を入れようと思います。 | A | B |C 1| AA| 11| 2| AB| 12| Sub Macro1() Dim AA As Range, BB As Range, AB As Variant Dim myTbl As Range, myFld As Integer, i As Integer Set AA = Range("A1") 'AAの箱にA1の値を Set BB = Range("B1") 'BBの箱にB1の値を Set myTbl = Range("テーブル") 'myTblの箱にテーブルを myFld = 3 'myFldの箱に3列目 AB = AA & "." & BB 'A1とB1の値を入れる For i = 1 To myTbl.Rows.Count 'iはテーブルの1行目から最後の行まで If myTbl.Cells(i, myFld).Value = AB Then 'テーブルの1行目のCのセルにA1とB1の値を入れる Exit Sub End If Next End Sub と思うのですが、やはり動きません。 アドバイスをお願いします。

  • 【Excel】リストボックスにデータを重複せず昇順に表示する方法

    教えてください。 ユーザーフォームにリストボックス(Listbox1)があり、日付が昇順で入力されるようになっています。 ただし、この日付データは重複が多いため重複されないよう表示しようと下記のコードを記述しましたが「実行時エラー1004 アプリケーション定義またはオブジェクト定義のエラーです」と表示されてしまいます。 これを回避し、実行させるためにはどういう風に記述を修正したらよいでしょうか? ================================================================ Private Sub UserForm_Initialize() Dim i As Long For i = 2 To 2000 ListBox1.AddItem Worksheets("データ").Cells(i, 1) Dim myValue As Variant Dim myRng As Range, myCell As Range Set myRng = Worksheets("データ").Cells(i, 1).End(xlUp) myValue = myRng.Value Application.ScreenUpdating = False myRng.Sort Worksheets("データ").Cells(i, 1), xlAscending, Header:=xlYes With ListBox1 .Clear For Each myCell In myRng.Resize(myRng.Rows.Count - 1).Offset(1) _ .SpecialCells(xlCellTypeVisible) .AddItem myCell.Value Next .ListIndex = 0 End With Next i ListBox1.ListIndex = 0 End Sub ================================================================

  • テキストボックス空欄への追加入力

    リストボックス1であ行の氏名項目を選択実行しテキストボックス1~8に入力された後にか行にリストボックス項目を変え氏名を選択実行した場合、下記のコードではテキストボックス1からまた上書きされる。テキストボックス空欄に続けて選択項目が入力される方法はあるのでしょうか。悩んでいます。どなたかコードがわかる方よろしくお願いします。 Private Sub 実行Cnd_Click() Dim cnt As Integer   Dim i As Integer If ListBox1.ListIndex = -1 Then Exit Sub cnt = 1 For i = 0 To ListBox1.ListCount - 1 If ListBox1.Selected(i) Then Me.Controls("TextBox" & cnt).Text = ListBox1.List(i) cnt = cnt + 1 End If Next End Sub

  • vbaで配列に値を格納する場合

    vbaで配列に値を格納する場合 変数の宣言はどちらを使った方が良いのでしょうか? Sub Sample1() Dim i As Long Dim myStr As String Dim tmp() As String myStr = "a,i,u,e,o" tmp = Split(myStr, ",") End Sub か Sub Sample1() Dim i As Long Dim myStr As String Dim tmp As Variant myStr = "a,i,u,e,o" tmp = Split(myStr, ",") End Sub でも問題なく動くのですが、 Variant型での宣言はあまりしない方が良いですか? あと Dim tmp() As String ならエラーにならないのですが Dim tmp As String だとエラーになってしまう理由がよくわからないので教えて頂けますか?

  • Excel マクロのFor~Nextで再起動エラー

    勤務表を作っています。 下記の’OKまでは希望どうりうまく出来ていたのですが、勤務表の下セルに各列の人員(行)10名分位A,B,Cの計を表示させたい。実行するとエラー「Microsoft office Excel 再起動」を求められます。  for~が判断指令が<重い>のでしょうか。なんとか回避さする方法を教えてください。 Win XP Sp2 Office Excel 2007です。今回これを作るにあたり初VBA使用者です。 ' C入力後の翌日は休をセット。CC連続は休休セット。 Private Sub Worksheet_Change(ByVal Target As Range) Dim cnt As Variant Dim a1 As Byte Dim b1 As Byte Dim c1 As Byte Dim nin As Variant Dim retsu As Variant If Target.Count > 1 Then Exit Sub '複数セルの入力は無視 'A If Target.Value = "A" Or Target.Value = "A" Then Target.Value = "A" Range("AV16").Value = Target.Column End If 'B If Target.Value = "B" Or Target.Value = "B" Then Target.Value = "B" Range("AV16").Value = Target.Column End If 'C If Target.Value = "C" Or Target.Value = "C" Then Range("AV16").Value = Target.Column Target.Value = "C" Else End If ' If Target.Value = "C" Then If Target.Offset(0, -1).Value = "C" Then 'Cが連続したら Target.Offset(0, 1).Resize(1, 2).Value = ("休") '連休に Else End If Target.Offset(0, 1).Value = ("休")   'そうでなければ休 End If 'A,B,C の数をカウントする。 nin = Range("AV15")  '別のプログラムから入力した人員数 retsu = Range("AV16")  ' A,B,Cのいずれかを入力したセル列。Target.Column ’OK For cnt = 7 To (6 + nin) If cells(cnt, retsu) = "A" Then a1 = a1 + 1 End If If cells(cnt, retsu) = "B" Then b1 = b1 + 1 End If If cells(cnt, retsu) = "C" Then c1 = c1 + 1 End If Next cnt cells(nin + 7, retsu) = a1 'A番 cells(nin + 8, retsu) = b1 'B番 cells(nin + 9, retsu) = c1 'C番 End Sub

  • 二次元配列のVBA

    二次元配列のVBAの書き方がよくわからないのですが、 私が作ったサンプルプログラムのSub 二次元()において 二次元配列で表すにはどうすればいいのでしょうか? Sub 二次元()では 配列を格納する変数はtmpしか使っていませんが もう一つ配列を格納する用の変数を作ればいいのでしょうか? 数字とアルファベットは別々に取り出したいです。 ----------------------------------------------------- Sub 一次元() Dim myStr As String Dim tmp As Variant Dim i As Long For i = 1 To 5 myStr = myStr & "," & i Next myStr = Mid(myStr, 2) tmp = Split(myStr, ",") For i = LBound(tmp) To UBound(tmp) Debug.Print tmp(i) Next i End Sub Sub 二次元() Dim myStr As String Dim tmp As Variant Dim i As Long For i = 1 To 5 myStr = myStr & "," & i & "と" & Chr(64 + i) Next myStr = Mid(myStr, 2) tmp = Split(myStr, ",") For i = LBound(tmp) To UBound(tmp) Debug.Print tmp(i) Next i End Sub

  • For~Nextステートメント  途中で止めるには

    For~Nextステートメント で、変数が5なら止めたいのですがIFを使わない方法があったと思うのですが、 忘れてしまいました。 今は、 +++++++++++++++++++++++++++++ Sub test() Dim i As Long For i = 2 To 10 If i = 5 Then Stop End If Next End Sub +++++++++++++++++++++++++++++ としていますが、 If i = 5 Then Stop End If じゃなくても、一つのメソッドで出来た気がするのですが、 わかる方いらっしゃいますか? ご回答よろしくお願いします。

  • Access VBA でのFor_Nextステートメントで使用例の意味が理解できず困っています

    Access VBA の勉強を始めて間もないものですが、あるテキストのFor_Nextステートメント使用の一部分の意味がわかりません。教えてください。 Sub ループのネスト() Dim i As Integer, j As Integer Dim myStr As String '九九の結果を表示する For i = 1 To 9 For j = 1 To 9 myStr = myStr & i * j & " " Next j MsgBox myStr, , i & "の段" myStr = "" Next i End Sub 以上の文面で(1)『myStr = myStr & i * j & " "』でmystrにmyStr & i * j & " "を代入する意味だとは理解できますがmystr&を右辺に記載する意味がわかりません。何故必要でしょうか? (2)『mystr=""』は何故必要なのでしょうか?

  • 統合セルのマクロ処理について

    お世話になっております。 現在マクロにて選択した範囲のセルにおいて 半角・全角・単語の書式を統一する処理をおこなっていますが、 統合されたセルが入ってくるととたんに処理に時間がかかってしまいます。 (対象となるシートの書式はさまざまです。) なんとか解消したいのですが、ご教示お願いできませんでしょうか? 以下マクロになります。 すみませんが、なにとぞよろしくお願い致します。 Sub 書式定義Macro() Dim c As Range Dim myStr As String Dim Match As Object, Matches As Object With CreateObject("VBScript.RegExp") .Pattern = "[\uFF61-\uFF9F]+" '---(1) .Global = True For Each c In Selection myStr = c.Value If Len(myStr) > 0 Then Set Matches = .Execute(myStr) 'マッチしたすべての文字列を全角へ置換 For Each Match In Matches myStr = Replace(myStr, Match.Value, _ StrConv(Match.Value, vbWide)) '---(2) Next Match c.Value = myStr End If Next c End With With CreateObject("VBScript.RegExp") .Pattern = "[0-9]+" '---(1) .Global = True For Each c In Selection myStr = c.Value If Len(myStr) > 0 Then Set Matches = .Execute(myStr) 'マッチしたすべての文字列を半角へ置換 For Each Match In Matches myStr = Replace(myStr, Match.Value, _ StrConv(Match.Value, vbNarrow)) '---(2) Next Match c.Value = myStr End If Next c End With With CreateObject("VBScript.RegExp") .Pattern = "[\uFF20-\uFF60]+" '---(1) .Global = True For Each c In Selection myStr = c.Value If Len(myStr) > 0 Then Set Matches = .Execute(myStr) 'マッチしたすべての文字列を半角へ置換 For Each Match In Matches myStr = Replace(myStr, Match.Value, _ StrConv(Match.Value, vbNarrow)) '---(2) Next Match c.Value = myStr End If Next c End With Dim r As Range 'ここの処理が統合セルの処理の際重くなる。 For Each r In Selection.Cells.SpecialCells(xlCellTypeConstants, xlTextValues) r.Value = Replace(r.Value, "デジカメ", "デジタルカメラ") r.Value = Replace(r.Value, "携帯", "携帯電話") r.Value = Replace(r.Value, "仮開通試験", "") r.Value = Replace(r.Value, "入管", "入館") r.Value = Replace(r.Value, "センタ", "センター") r.Value = Replace(r.Value, "オーナ", "オーナー") r.Value = Replace(r.Value, "パートナ", "パートナー") r.Value = Replace(r.Value, "マネージャー", "マネージャ") r.Value = Replace(r.Value, "リーダー", "リーダ") r.Value = Replace(r.Value, "メンバー", "メンバ") r.Value = Replace(r.Value, "サマリー", "サマリ") r.Value = Replace(r.Value, "サーバー", "サーバ") r.Value = Replace(r.Value, "ルーター", "ルータ") r.Value = Replace(r.Value, "ファイアーウォール", "ファイアーウォール") r.Value = Replace(r.Value, "プロキシー", "プロキシ") r.Value = Replace(r.Value, "インタフェース", "インターフェース") r.Value = Replace(r.Value, "マネージメント", "マネジメント") r.Value = Replace(r.Value, "ウィルス", "ウイルス") r.Value = Replace(r.Value, "マスタ", "マスター") Next r '処理結果の一部修正 Dim myCell As Range For Each myCell In Selection '.Cells.SpecialCells(xlCellTypeConstants, xlTextValues) myCell.Value = Replace(myCell.Value, "(", "(") myCell.Value = Replace(myCell.Value, ")", ")") myCell.Value = Replace(myCell.Value, "携帯電話電話", "携帯電話") Next myCell MsgBox (" 処理が完了しました ") end sub 以上です。

専門家に質問してみよう