• ベストアンサー

VBA Forネストのしすぎ

VBA Forネストのしすぎ 漠然とした質問で申し訳ないのですが VBAに限らず他の言語でも For のネストを多用する傾向にあり 4,5重になってしまい管理が煩雑になったり (他人から見て恐らく)分かりにくいソースになってしまいます 例えば、 ある要素のString一致を探して それを相対参照して一致を探しつつ 更に別のBooleanリストから値の一致を探す。。。 と言った具合です こういった複数の検索をスマートにコーディングする方法はあるでしょうか。

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

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

抽象的すぎて、質問の意図がわかりにくい。 学が深くないので、自信はないが、関心はあり、一読を願う。 VBA程度では大した仕掛けはないが、SQLもVBSCRIPTの元で色んなソフトも 使える。それなりにソフトを作れば(MSや業者、識者、質問者でも)、エクセルVBAの元でも使えるソフトは作れる。 ・例えばデータベースなどで、SQL文で、WHERE句で3条件を書いて、該当のものレコードを求める場合、思考パターンとしては、多段ネストになると思うが、それを表に出さず、ユーザーに気づかせることはない仕組みを作っている。 ・また仕組み的に(事前に)インデックスを作っておいて、それを使うやり方ならForNextを使っているかどうかにかかわらず、意識させないのでは。 ・データの中から、該当を探すときに、シーケンシャルサーチ(時間がかかる)を使わないのは、どうしたらよいか、学問上の大問題と思うから、質問者が将来勉強するほかないと思うが。 基本的に下記と下記同士の組み合わせ ・総なめ法(シーケンシャルサーチ) 全部で・部分的で利用 ・ハッシュ法 ・インデックス(索引)作成法

その他の回答 (3)

  • okgoo3
  • ベストアンサー率74% (20/27)
回答No.4

VBA で作るコードは開発者が希望している特定の処理を実装するものなので、一つのプロシージャーに処理を詰め込みすぎてしまう事があります。 ドキュメントが整備されておらず、コメントだけですべてを語ろうとするケースでは、コードの読み手が業務そのものの知識をどれだけ持っているか、コードを読み解く言語知識がどれだけあるかによって許容できるコードの長さも変ってしまう。 気になるのであれば、ネストの深い部分にある処理を同じモジュールに private な Sub もしくは Function に切り分けると良いかと。 ただし分けることによるトレードオフも発生します。 プロシージャ間でどのようにデータを授受するか、エラー処理は発生したプロシージャ内で処理をしてしまって呼び出し元にはエラーが起きたことを返すのか、それともエラーそのものを呼び出し元に返して上位の呼び出しもとでエラー処理をするのか、などなど。 気になってくることが出てくるはずです。 そしてプログラミングの力量が付いてきた数年後にコードを読み返すと、「なぜこんなブツブツに処理を分断しているんだ。 このぐらい一気にやっちゃえよ」などと思ってしまったり。

  • hue2011
  • ベストアンサー率38% (2800/7250)
回答No.3

インデンテーションをきっちりすることです。 それだけで可視性は上がります。 VBAはスコープによって変数の有効範囲が違うなんていうことがありませんから、べたでタイプしてしまうんです。

回答No.1

思いつくのはこれかなあ /* C# */ for (int i = 0;i < 10;i++){ for(int j = 0; j < 10; j++){ for(int k = 0; k < 10; k++){ // 何か } } } ⇒ for (int i = 0;i < 10;i++){ for(int j = 0; j < 10; j++){ doSomething(list1); } } void doSomething(List<int> list1){ for(int i = 0; i < 10; i++){ // 何か } }

関連するQ&A

  • vbaでfor nextの計算

    vbaでfor nextを使って計算しています。 excelのシートの値を使って計算しています。 for nextが3重になっていて中のyとxのfor next が計算し終わったらjのfor nextで次のセルを参照したいのですがうまくいきません。 どうしたらいいか教えてください。 コードは以下の通りです For j = 1 To 2 Step 1 For y = 3 To 90 Step 3 γ = y / 180 * π For x = -180 To 180 Step 6 α = x / 180 * π γs = Range("A:A").Rows(j).Value / 180 * π αs = Range("B:B").Rows(j).Value / 180 * π Eeg = Range("C:C").Rows(j).Value Eed = Range("D:D").Rows(j).Value 計算式(省略) Next x Next y Next j

  • vbaにおいて、セルのエラー検出に関して

    vbaにてセルに入力する数式のエラー検出に関して教えてください。 iserror関数で検出できない数式を簡単に検出する方法ありませんか? sub test() dim str as string str=" C2*C3* " cells(5,7).value=str end sub 簡単なVBAのコードですが、*の右側はセル相対参照もセル絶対参照も数値も入っていませんので、数式としてはエラーです。 strの値を(5,7)のセルに放り込んだら、vbaのエラーで停止してしまいます。 かといって、iserror()を使って、 sub test() dim str as string str="C2*C3*" if iserror(str)=true then else cells(5,7).value=str end if end sub としても、エラーをはじいてくれず、VBAでもエラーを出力してしまいます。 力業で、strの数式エラーをはじくしか方法はないのでしょうか? インターネットを調べているのですが、的を射た答えが出てきません。 どなたか詳しい方ご教示ください。

  • 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=""』は何故必要なのでしょうか?

  • 拡張for文について質問

    以下は、拡張for文と配列に関するソースコードの一部を抜粋したものです。 それを見た上で、私の質問に答えてください。 int[]a={10,5,8,4,3}; for(int n:a){ System.out.print(n+" "); } int[][]a={{1,2},{4,5,6}}; for(int[]n:a){ for(int k:n){ System.out.print(k+" "); } System.out.println(""); } 質問1:何故、前者の配列は、『for(int n:a)』のように[]がついてなくても配列要素が取り出せるのに、後者の多次元配列は『for(int[]n:a){』のように『[]』がついた拡張for文を書いた上で、下にも拡張for文を書いた2重構造でないと配列要素を取り出せないのですか? 後者について『for(int n:a){』の文だけで多次元配列aの要素全て取り出せると思ってました。 因みに、配列変数には配列要素が入ってるのではなくて「参照」が入ってるのはわかってます。 このことと、何か関係があるのか、、?

    • ベストアンサー
    • Java
  • vbaの正規表現で、マッチした一部分を抽出したい

    accessの正規表現で、マッチした部分の一部を取り出したいと思っています。 秀丸で言えば、 ------------------------ 文字列 あいうえお ↓↓↓ 正規表現 あ(.*)お 置き換え文字 \1 ↓↓↓ 抽出 いうえ ------------------------ って感じの「¥1」みたいなのがほしいと考えています。 現在、下記のような感じで、対象文字を抽出しています。 ここから、また正規表現でほしい部分を抽出しなければいけないのでしょうか? 【上の例で言えば、「あいうえお」を抽出する関数】 ------------------------ Function 抜き出し(ByVal 指定文字列 As String) As String Dim 正規表現, 一致集団, 一致要素 Set 正規表現 = CreateObject("VBScript.RegExp") 正規表現.Pattern = "購入日時[0-9]{4}年[0-9]{1,2}月[0-9]{1,2}日 [0-9]{1,2}時[0-9]{1,2}分" 正規表現.MultiLine = True Set 一致集団 = 正規表現.Execute(指定文字列) For Each 一致要素 In 一致集団 抜き出し = 一致要素.Value Exit For Next End Function ------------------------ これだと、 購入日時2012年1月25日 17時53分 がマッチします。 でもほしいのは、 2012年1月25日 17時53分 の部分だけ。 何かいい方法は無いでしょうか? よろしくお願いします。

  • VBA for Excel でファイルを条件付きで開く

    VBA for Excel で、開いているか開いていないか判らないファイルを開きたいと思い(ファイルは2つ、名前はGRT と GTATNO という変数に入っている)、下記のように書いてみましたが、Excel2000 ではエラーが起きるようです。 Sub ファイルを開く Dim hbook As Workbook AP = ActiveWorkbook.Path 'ファイルが開いていたら何もしない For Each hbook In Workbooks If hbook.Name <> GRT Then Workbooks.Open (AP & "\" & GRT) End If If hbook.Name <> GTANTO Then Workbooks.Open (AP & "\" & GTANTO) End If Next End Sub 原因は、そのときゲットした開いているファイル名(hbook.Name)がたまたま一致しないときにファイルを開こうとしてしまう、ということは判りました。 こうなると「2重に開こうとしている。開いて良いか?」のメッセージが表示され、それにNoと答えるとマクロがエラーを表示し、利用者は困ってしまうのですが、 どうしたらうまく動くマクロになるのかがわからず、悩んでいます。 ほとんど「組んでちょーだい」状態ですが、よろしくお願いいたしますm(_ _)m また職場でネットしているため、解答いただいた時間によってはお礼が8日(月)になってしまいますことを、予めお断りしお詫びしておきます。

  • VBAでファイルを開いてないときに開くコード

    いつもお世話になります。 VBA(Excel2007)の初心者です。 目的のファイルが開いていない時は開き、 既に開いている時は何もしない。 という処理をしたいと思い以下のコードを 書きました。 Dim wb As Workbook Dim myfilename As String For Each wb In Workbooks If wb.Name = "予定表.xls" Then Exit For Else myfilename = "\\___\__\予定表.xls" Workbooks.Open Filename:=myfilename End If Next wb 実行したら何度もファイルを開こうとしてしまいます。 どこに問題があるのでしょうか? ちなみにこれは"予定表.xls"のセルを参照したくて ある処理の前に実行するつもりなのですが、 別のブックのセルを参照するときはやはり そのブックを開かなくてはならないのでしょうか? 何卒よろしくお願いします。

  • EXCEL VBAについて(再質問)

    お世話になります。 EXCEL VBAで指定したフォルダのEXCELブックが1つでもオープンされているかどうか知りたいのですが、可能でしょうか。 という質問を行い、以下の回答をいただきました。 自分でテストしてみてできたと思ったのですが、 他の人が開いているのが分かりませんでした。 他の人がオープンしているかどうか知ることは可能でしょうか? よろしくお願いします。 以下の回答といただきました。 ------------- ※[ツール]-[参照設定]で Microsoft Scripting Runtimeにチェック入れて下さい。 Dim Fso As New FileSystemObject 'ファイルシステムオブジェクト Dim xlBook As Workbook '開かれているブック Dim objFolder As Folder '調べるフォルダ Dim bOpenedBook As Boolean '開かれているかフラグ '調べるフォルダを「C:\tmp」とする。 Set objFolder = Fso.GetFolder("C:\tmp") bOpenedBook = False '今開かれているブックでループする。 For Each xlBook In Excel.Workbooks If Len(xlBook.Path) > 0 Then 'ブックが保存されているフォルダと調べるフォルダが一致するか? If objFolder Is Fso.GetFolder(xlBook.Path) Then '一致すれば開かれている bOpenedBook = True Exit For End If End If Next '結果をメッセージボックスで表示 If bOpenedBook Then MsgBox "開かれています。" Else MsgBox "一つも開かれていません。" End If

  • Excel for mac 2011でDir関数?

    Excel for mac 2011でDir関数を使用したファイルサーチが出来ません。なぜなのでしょうか? 使用環境は、Excel for mac 2011 ver. 14.1.0, MacOS X 10.6.7, MacBook Airです。 働いている研究室がMac onlyのため、Mac版のExcelにvbaを移植しようと考えているのですが、以下のプログラムが上手く動きません。 ------------------vbaプログラム Private Sub CommandButton1_Click() Dim strPATHNAME As String ' 指定フォルダ名 Dim strFILENAME As String ' 検出したファイル名 Dim ExistFILE As Boolean ' "*.TXT"ファイルの判定 ' 「フォルダの参照」よりフォルダ名の取得 strPATHNAME = MacScript("choose folder") strPATHNAME = Mid(strPATHNAME, 7) 'aliasを削る If strPATHNAME = "" Then Exit Sub ' 指定フォルダ内のTEXTのファイル名を参照する strFILENAME = Dir(strPATHNAME, vbNormal) '<------ここでファイルを検出しない。 ExistFILE = strFILENAME Like "*.TXT" If strFILENAME = "" Then MsgBox "このフォルダにはTXTファイルは存在しません。" Exit Sub End If End Sub ------------------ 上記プログラムは、コマンドボタンを押すとフォルダを指定して、その中の”.TXT”という拡張子のついたファイルを見つけるプログラムです。(実際には何もしないダミープログラムですが) しかしこれを実行すると、Dir関数の所で何も検出してくれません。 ローカル変数を追って、フォルダまでのパスにカタカナが入ったらダメだとか、”alias”が邪魔だとかは解決したのですが、肝心のDir関数が上手く動いていないことに気づきました。 どなたか詳しい方にお願い致します。 どうすれば、指定したフォルダ中の拡張子”.TXT”がついたファイルを見つけることが出来るのか?教えて頂ければ幸いです。

  • 【VBA】A1参照形式のままR1C1形式で条件書式

    ExcelでA1参照形式のまま、VBAで数式などR1C1形式で入れたとしても、たいていは自動でA1形式に変換してくれますよね。 ただ、例えば列は絶対参照にしたい場合、"$A1"をR1C1形式で記入すると"RC1"となり、A1参照形式のままだとRC列の1行目として認識しA1形式に変換してくれないんですよね(^_^; この度、2つの列の値を比べて相違するものだったらセルの色を変える条件書式を入れるVBAを書いたんですが、 Selection.FormatConditions.Add Type:=xlExpression, Formula1:= "=AND(RC2<>"""",RC1<>RC2)" 「B1セルが空欄ではなく、A1セルとB1セルが一致しないなら……」 という条件にしたいのに、A1参照形式のときにうっかりこれで入れてしまうと、 「RC1セルが空欄ではなく、RC1セルとRC2セルが一致しないなら……」 と、まあ案の定入ってしまうわけです(^_^; こういうのを防ぐために本来はApplication.ReferenceStyleを使って現在の形式を判定し、R1C1参照形式に変更してから入れるようにすれば良いんですが、今回別のブックからデータを引っ張ってくるという手順もあるマクロで、そっちのブックでセル参照と同じ名前を定義してるものがあるらしく、エラーとなって変更することができません。 まあマクロ自体をA1形式で書くようにすればいいじゃないかとも思うんですが、作り的にVBAはR1C1形式で書きたい。 「RC<>RC[1]」と「RC[-1]<>RC」と相対参照にしてA列、B列それぞれに入れる方法もありますが、条件書式が増えるのも気持ち悪いし、何だか負けた気がして嫌(笑) なんとかA1参照形式のままR1C1形式で条件書式をVBAで書き込む方法はないでしょうか? さすがに仕様ということで無理でしょうかね?(^_^;

専門家に質問してみよう