VBAのFormulaArrayについて

このQ&Aのポイント
  • VBAのFormulaArrayに関して、エクセルで統計処理をする際に問題が発生しています。特定の関数が正常に動作せず、処理が途中で無視されてしまいます。エラーは発生しておらず、原因がわからず困っています。
  • 該当の関数は他の場所で正常に動作していることが確認されており、参照設定やシートの保護にも問題はありません。
  • WindowsXPとエクセル2007を使用しており、問題が発生しているコードは5年前に作成されたものです。どのように修正すれば問題が解決するか、ご教示いただきたいです。
回答を見る
  • ベストアンサー

VBAのFormulaArrayについて

VBAについて調べても原因がわからなかったため質問です。 エクセルで統計処理をする先人が書いたコードが動かないため、デバッグしています。 OSはWindowsXP、エクセルは2007です。 先人が作成していた環境はわかりませんが、5年前に書いたようです。 この時点であきらめろよという話ですが、そうもいかない状況なので一つお付き合いください。 下記の関数の挙動がおかしいです。 Sub 標本入力()    ・・・・省略・・・   If ActiveSheet.Name = "連鎖独立グラフ" Then 連鎖独立シート初期化 3 Else  ・・・・省略・・・ Range("C301").Select Selection.PasteSpecial Paste:=xlValues 独立シート初期化 3 End If Application.CutCopyMode = False Cells(11, 3).Select End Sub 独立シート初期化(n)  'nは相関行列の変数の個数 ActiveWorkbook.Names.Add Name:="母相関", RefersTo:=Range(Cells(51, 4), Cells(50 + n, 3 + n)) ActiveWorkbook.Names.Add Name:="偏相関", RefersTo:=Range(Cells(101, 4), Cells(100 + n, 3 + n)) ActiveWorkbook.Names.Add Name:="相関残差", RefersTo:=Range(Cells(151, 4), Cells(150 + n, 3 + n) ・・・・省略・・・ Range("母相関").FormulaArray = "=標本相関-相関残差-TRANSPOSE(相関残差)" Range("偏相関").FormulaArray = "=-逆行列/SQRT(対角*TRANSPOSE(対角))" '★この行を処理していない!! Range("逆行列").FormulaArray = "=MINVERSE(母相関)" ・・・・省略・・・ End ★のついたコメントの前の行にさしかかると、それ以降の処理が無視されて標本入力()の処理に戻り、Ifを抜けて「Application.CutCopyMode = False」以降の処理にかかってしまいます。 デバッグしたところ、どうもFormulaArrayがあると処理を無視してしまうようです。しかしエラーは出てこないので、どう改善していいかがわかりません…他の関数で利用されているFormulaArrayはどうも正常に動いているようなのです。 参照設定はデフォルトの状態からSOLVERのみ追加しており、シートの保護はかけていません。 ど素人なので、不明な情報がありましたら追記致します。どうか、御教示頂けると幸いです。

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

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

>どう改善していいかがわかりません 再現性が取れないので、質問内容では、正確な原因は分かりません。 あくまでも想像の範囲は越えません。 まず、「逆行列」の名前の定義のコードは、たぶん、省略してしまったのでしょうね。 ご質問上のコードでは、唐突に出てきているように見えます。 いずれにしても、逆行列のマトリックス(=計算表)がシート上に置いてあるのでしょうから、私は、そのコードの再現性を試すことは出来ませんが、ExcelのMinversの逆行列は、サイズが非常に小さかったと思います。その逆行列の計算は、手動で値が出るのでしょうか?(数式のセルにカーソルを乗せ、F2で開けて、再度、Shift+Ctrl - Enterで、配列確定をすれば出るはずです) 一度、手動で試してみたほうがよいです。 正直なところ、Excelの関数を使ってでは、大したことは出来ないはずです。コードとして、FormulaArray は問題ありません。 それと、私の悪い想像だけであってほしいのですが、サブ・プロシージャ上で、ActiveWorkbook.Names.Add という使い方をしていますが、VBAでは、Namesのプロパティが二重の登録になりかねません。本来は、二重登録などありえないことです。なぜ、トラブルが起こるのか正確な理由は分かりません。 私の推測では、Namesの親オブジェクトが、シート、ブック、アプリと何種類もあるということが問題点です。コードとしては、論理的には正しいのですが、実務的には、そのVBAのコードは、トラブルが出やすいのではないかと思います。できれば、名前の定義登録のように、ひとつのブックで1回限りのようなメソッドは、手動でやったほうがよいのです。 もし、範囲指定が、その都度変わるなら、名前の定義登録だけのマクロを置いたほうがよいです。 そうでなかったら、単に、Rangeプロパティに、パラメータとして範囲を入れてあげたほうが、簡単だと思います。 コンピュータ用語が多いので、文章が分かりにくかったらすみません。

HiK0909
質問者

お礼

情報少ないのにご回答頂いてありがとうございます。あまりに長いコードでして、省略せざるを得えませんでした。ご指摘頂いたところをもう少し考えてみます。

関連するQ&A

  • セルに名前をつける

    excel2003 セルに名前を付与するマクロで繰り返し処理する設定を教えていただきたく。 構成: D12からD36のセルまで1行おきに名前をつけたい名称が13ケ登録されています 結合されたセルが (1)AG11:AH12、AG13:AH14、AG15:AH16…AG35:AH36 全部で13ケ (2)AI11:AJ12、AI13:AJ14、AI15:AJ16…AI35:AJ36 全部で13ケ 存在します (1)のセル名称はD12を参照し先頭には_CKC_を付加、末尾には_1を付加 (2)のセル名称はD12を参照し先頭には_CKC_を付加、末尾には_0を付加 という内容を下記のマクロで作成しました。 Sub Sample1() Dim name1 As String Dim name2 As String Dim name3 As String Dim name4 As String Dim name5 As String Dim name6 As String Dim name7 As String Dim name8 As String Dim name9 As String Dim name10 As String Dim name11 As String Dim name12 As String Dim name13 As String name1 = Range("D12") Names.Add name:="_ckc_" & name1 & "_0", RefersTo:="=$AG$11" Names.Add name:="_ckc_" & name1 & "_1", RefersTo:="=$AI$11" name2 = Range("D14") Names.Add name:="_ckc_" & name2 & "_0", RefersTo:="=$AG$13" Names.Add name:="_ckc_" & name2 & "_1", RefersTo:="=$AI$13" name3 = Range("D16") Names.Add name:="_ckc_" & name3 & "_0", RefersTo:="=$AG$15" Names.Add name:="_ckc_" & name3 & "_1", RefersTo:="=$AI$15" name4 = Range("D18") Names.Add name:="_ckc_" & name4 & "_0", RefersTo:="=$AG$17" Names.Add name:="_ckc_" & name4 & "_1", RefersTo:="=$AI$17" name5 = Range("D20") Names.Add name:="_ckc_" & name5 & "_0", RefersTo:="=$AG$19" Names.Add name:="_ckc_" & name5 & "_1", RefersTo:="=$AI$19" name6 = Range("D22") Names.Add name:="_ckc_" & name6 & "_0", RefersTo:="=$AG$21" Names.Add name:="_ckc_" & name6 & "_1", RefersTo:="=$AI$21" name7 = Range("D24") Names.Add name:="_ckc_" & name7 & "_0", RefersTo:="=$AG$23" Names.Add name:="_ckc_" & name7 & "_1", RefersTo:="=$AI$23" name8 = Range("D26") Names.Add name:="_ckc_" & name8 & "_0", RefersTo:="=$AG$25" Names.Add name:="_ckc_" & name8 & "_1", RefersTo:="=$AI$25" name9 = Range("D28") Names.Add name:="_ckc_" & name9 & "_0", RefersTo:="=$AG$27" Names.Add name:="_ckc_" & name9 & "_1", RefersTo:="=$AI$27" name10 = Range("D30") Names.Add name:="_ckc_" & name10 & "_0", RefersTo:="=$AG$29" Names.Add name:="_ckc_" & name10 & "_1", RefersTo:="=$AI$29" name11 = Range("D32") Names.Add name:="_ckc_" & name11 & "_0", RefersTo:="=$AG$31" Names.Add name:="_ckc_" & name11 & "_1", RefersTo:="=$AI$31" name12 = Range("D34") Names.Add name:="_ckc_" & name12 & "_0", RefersTo:="=$AG$33" Names.Add name:="_ckc_" & name12 & "_1", RefersTo:="=$AI$33" name13 = Range("D36") Names.Add name:="_ckc_" & name13 & "_0", RefersTo:="=$AG$35" Names.Add name:="_ckc_" & name13 & "_1", RefersTo:="=$AI$35" End Sub 付与したい名称が13ケであれば、上記の通りベタでも対応可能ですが、 付与したいセルが多くなった時、ベタで対応するのは大変なので、 Nケの名前を付与させるマクロを教えていただきたく。 マクロ初心者なので、VBAはベタで教えてください。

  • Excel VBA セル範囲に名前をつける

    Excel VBA独学中の初心者です。 セル範囲に名前をつける方法で以下の2つの方法があるようです。 (1) 同じように動作しますが違いは有るのでしょう。 (2) 本質的に考え方または内部動作は違うのでしょうか。 お分かりの方教えていただけますと助かります。 --------------- '方法1 Sub 名前の定義1() Range("sheet1!A2:B3").Name = "名前1" End Sub '方法2 Sub 名前の定義2() Range("A1").Select ActiveWorkbook.Names.Add Name:="名前2", _ RefersTo:="=sheet1!A2:B3" End Sub

  • 範囲に名前を付けたいのですが vba

    vbaでA1から2列目の最終行までの範囲に名前を付けたいのですが ActiveWorkbook.Names.Add Name:="範囲の名前", RefersToR1C1:="=Sheet1!R1C1:INDEX(Sheet1!C2,COUNTA(Sheet1!C1))" これで出来るのですが、 R1C1方式じゃない書き方にしたいのですが ActiveWorkbook.Names.Add Name:="範囲の名前", RefersToRange:="=Sheet1!$A$1:INDEX(Sheet1!$B:$B,COUNTA(Sheet1!$A:$A))" だと、「名前付き引数が見つかりません」になります。 RefersToRangeの部分が違うのと思うのですが、どうすればいいでしょう???

  • VBA で名前の定義をしたいのですが・・・

    初心者です。 いろいろ試してみたのですが、だめでした。 ご教授ください。 対象という名前を定義させたいと思っています。 定義の参照範囲は可変です。 定義したい範囲はSheet1のAA3からAAの最終行までです。 それでマクロの自動記録から名前の定義のコードを取ってきて 変数を代入してみましたが、参照範囲を正しく取ってきてくれませんでした。 Sub test() '対象の名前を定義する Dim n As Long n = Sheets("Sheet1").Cells(Rows.Count, 27).End(xlUp).Row Sheets("Sheet1").Select Range(Cells(3, 27), Cells(n, 27)).Select ActiveWorkbook.Names.Add Name:="対象", RefersToLocal:="=Sheet1!R3C27:RnC27" End Sub RefersToLocal:="=Sheet1!R3C27:RnC27"の部分を RefersToLocal:="=Sheet1!R3C27:R&n&C27" RefersToLocal:="=Sheet1!R3C27:"R"&n&"C27"" にしてもだめでした。 うまく範囲をとってくれる方法を教えてください。 お願いします。

  • VBAで名前定義を変更するとき

    おはようございます。 ExcelVBAで教えてください。 名前の定義はマクロの自動記録で解りました。 ActiveWorkbook.Names.Add Name:="名前A", RefersToR1C1:="=参照範囲" のようになりました。 VBAで参照範囲を変更したいとき、どのようにするのでしょうか? 再度、ActiveWorkbook.Names.Add Name:="名前A", RefersToR1C1:="=参照範囲" としてもエラーにはならなかったのですが、すでに"名前A"があるのに Names.Addとするのはおかしいかと思いました。 それで、どのようにするのかお教えください。

  • VBAでの説明がわかりません

    以下のコードは、都道府県ごとに1枚のデータシートを作成する処理なんですが、コードが1行づつどんな作業を意味しているのかがわかりません。1行ごとにどのような処理をしているのかの説明をよろしくお願いします。長文で申し訳ありません。 Sub まとめ() Dim i As Integer 'カウンタ変数iの宣言 Dim n As Integer  Dim MyS1 As Worksheet 'ワークシート型オブジェクトMyS1を宣言 Dim MyC As Worksheet Worksheets.Add before:=Worksheets("全国") ActiveSheet.Name = "data" Set MyS1= Worksheets("data") With Worksheets("全国") MyS1. Range(MyS1.Cells(1,1),MyS1.Cells(11,12))=.Range(Cells(1,1),.Cells(11,12)).Value End With i=12 For Each MyC In Worksheets If MyC.Name<> "data" Then n = 12 MyS1.Cells(i,1)=MyC.Name i=i+1 Do While MyC.Cells(n,2).Value<>"" MyS1.Range(MyS1.Cells(i,1),MyS1.Cells(i,12))=MyC.Range(MyC.Cells(n,1),Mc.Cells(n,12)).Value i=i+1 n=n+1 Loop End If Next Myc End Sub

  • 名前の定義 R1C1形式で列を指定するには?

    Excel2003を使っています。 For i = 1 To Cells(1, 1).End(xlToRight).Column ActiveWorkbook.Names.Add Name:=Cells(1, i), RefersTo:="=Sheet1!C" & i Next このような形で1行目のセル内のデータを名前として定義しようと考えています。 A1形式で書くところの「=Sheet1!$A:$A」と列そのものを指定したいのですが、R1C1形式だと「=Sheet1!C1」となるはずですよね。 ですが、これを実行すると「=Sheet1!RC[2]」という見当違いのものが記入されてしまいます。 もちろん、これだとどこの列も指定していることにはなりません。 ちゃんとR1C1形式で記入する方法はありませんか? 列をずらしながら自動で定義していきたいので、A1形式だと難しいのです。

  • エクセルVBA 「名前の定義」について

    いつもお世話様です。エクセル2000での名前定義に関するVBA操作で疑問がありますのでよろしくお願い申し上げます。 (o。_。)oペコッ 以下のマクロで、あるエクセルのBOOKの名前の定義をすべて書き出してみました。 Sub Names_Check() Dim nm As Object Set sh = ActiveWorkbook.Worksheets.Add For Each nm In ActiveWorkbook.Names i = i + 1 sh.Cells(i, 1) = nm.Name sh.Cells(i, 2) = "'" & nm.RefersTo Next End Sub すると、なかにはセル範囲を参照していない名前の定義がけっこう見つかりました。 それらはよく見ると =○○○.xls!△△マクロ のようなマクロの名前を参照していました。 そんな名前の定義はつけた覚えが無いのですが、これは何でしょうか? なぜそのような名前の定義が出来てしまうのでしょうか? 次にセル範囲を参照していないこれらの名前定義を削除するため下記のマクロを書いてみたところ、「実行時エラー1004 その名前は正しくありません」というエラーがでてしまいます。 どう書いたら削除できるのでしょうか?(もちろん手動では削除できます。) Sub Del_NameRefQuestion() '不明な参照の名前定義削除 Dim nm As Object Dim mystr As String, ans As Integer For Each nm In ActiveWorkbook.Names If InStr(nm.RefersTo, "$") = False Then ans = MsgBox(nm.Name & "/" & nm.RefersTo, vbYesNo + vbQuestion, "削除しますか?") If ans = vbYes Then nm.Delete ’ここでエラー End If Next MsgBox "不明参照の名前定義削除完了", , " ( ̄ー ̄)v" End Sub

  • VBA : ピボットテーブルの作成

    下記の内容でマクロを記述しましたが、「Set pvt = ・・・」の時点で、「実行エラー '13' 型が一致しません」とエラーが生じてしまいます。 どの部分がいけないのでしょうか? よろしくお願い申し上げます。 ********************************************* Sub Macro1() Dim pvt As PivotTable Dim rngData As Range Dim shtName As String Dim mySht As Worksheet Sheets.Add 'シート名の変更 ActiveSheet.Name = "PVT123" For Each mySht In ActiveWorkbook.Worksheets shtName = mySht.Name If Left(shtName, 2) = "G-" Then mySht.Select Exit For End If Next '元データを変数に格納 lastRow = Cells(Rows.Count, 1).End(xlUp).Row lastClm = 1 Do Until Cells(1, lastClm).Value = "" lastClm = lastClm + 1 Loop lastClm = lastClm - 1 Set rngData = ActiveSheet.Range(Cells(1, 1), Cells(lastRow, lastClm)) 'ピボットテーブルの作成 Sheets("PVT777").Select Set pvt = _ ActiveWorkbook.PivotCaches.Add( _ SourceType:=xlDatabase, _ SourceData:=rngData). _ CreatePivotTable(TableDestination:=Range("A3")) ~以下省略~

  • EXCEL VBA シートのコピー後処理?

    EXCEL2013使用にてフォーム内ボタンより 下記、受注一覧表シートをコピー→一番左に配置して 処理シートに名前を変更して J列基準の昇順に並び変えようとしていますが ActiveSheet.Name = "処理シート"で コードの実行が中断されましたメッセージが出ます。 ActiveSheet.Name = "処理シート"にブレークポイントを置いて F8で進めていきますと処理実行します。 ユーザーフォームは UserForm1.Show 0で開いております。 どの箇所の修正を行えばいいのか ご教示時お願いいたします。 Private Sub CommandButton1_Click() Worksheets("受注一覧表").Copy Before:=Worksheets(1) ActiveSheet.Name = "処理シート" Worksheets("処理シート").Select Rows("8:2328").Select Range("B8").Activate ActiveWorkbook.Worksheets("処理シート").Sort.SortFields.Clear ActiveWorkbook.Worksheets("処理シート").Sort.SortFields.Add Key:=Range("J9:J2328") _ , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal With ActiveWorkbook.Worksheets("処理シート").Sort .SetRange Range("B8:L2328") .Header = xlYes .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With Range("B8").Select End Sub

専門家に質問してみよう