こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

エクセルマクロで定義した関数が動きません

以前にマクロの記述について教えて頂いた件の続きになります.
ご指導頂いたとおりExcelマクロで複素数を扱う関数を下記HPから
標準モジュールにコピペしました.今度は正しくコピーできたと思いますが,
実行するとエラーになります.
標準の組込み関数を用いて「実数」の行列を計算すれば正しく
計算できますが,当然ながら「複素数」は計算できません.
この「複素数」を扱う新しく定義した関数が動かない理由,
「End if に対するifブロックがありません」とか
計算結果が「#VALUE!」となってしまうのは何故でしょうか?
マクロの記述内容はほとんど理解できないのですが,
どなたか助けて頂けませんか!
ちなみにエクセルは2016版です.
http://www.geocities.jp/tomtomf/denki/AC2/ac2.htm
http://www.geocities.jp/tomtomf/denki/AC1/ac1.htm

以下はコピー定義した「 IMMULT」関数と「 IMINVERS」関数のマクロです.

Public Function IMMULT(a As Range, b As Range) As Variant
Dim r1 As Integer, r2 As Integer, c1 As Integer, c2 As Integer, nn As Integer
Dim r As Integer, c As Integer
Dim cr As Integer, cc As Integer
Dim n As Integer
Dim mm() As Variant

r1 = a.Rows.Count
r2 = b.Rows.Count
c1 = a.Columns.Count
c2 = b.Columns.Count
If (c1 = r2) Then
nn = c1
Else
Exit Function
End If
cr = r1
cc = c2
ReDim mm(1 To cr, 1 To cc)

For r = 1 To cr
For c = 1 To cc
mm(r, c) = 0
For n = 1 To nn
mm(r, c) = IMSUMa(mm(r, c), IMPRODUCTa(a.Cells(r, n), b.Cells(n, c)))
Next
Next
Next
IMMULT = mm
End Function

Public Function IMINVERS(a As Range) As Variant

Dim n As Integer, n1 As Integer, n2 As Integer
Dim r1 As Integer, r2 As Integer, c As Integer
Dim max As Variant
Dim i As Integer
Dim m() As Variant
Dim inm() As Variant
Dim rr As Integer, cc As Integer
Dim no As Integer, ex As Variant

n1 = a.Rows.Count
n2 = a.Columns.Count
n = n1

ReDim inm(1 To n1, 1 To n2)

For rr = 1 To n1
For cc = 1 To n2
If rr <> cc Then inm(rr, cc) = 0 Else inm(rr, cc) = 1

'End If

Next
Next

ReDim m(1 To n1, 1 To n2)

m = a

If n1 <> n2 Then IMINVERS = False

Exit Function

End If

For r1 = 1 To n
max = m(r1, r1)
no = r1
If r1 < n Then
For i = r1 + 1 To n
If IMABSa(m(i, r1)) > IMABSa(max) Then max = m(i, r1)
no = i
End If
Next

If (r1 <> no) Then
For i = 1 To n
ex = m(r1, i)
m(r1, i) = m(no, i)
m(no, i) = ex
Debug.Print m(r1, i), m(no, i)

ex = inm(r1, i)
inm(r1, i) = inm(no, i)
inm(no, i) = ex
Next
End If

End If

max = m(r1, r1)

For i = 1 To n
m(r1, i) = IMDIVa(m(r1, i), max)
inm(r1, i) = IMDIVa(inm(r1, i), max)

Next

For r2 = 1 To n
If r1 <> r2 Then

max = m(r2, r1)

For i = 1 To n
m(r2, i) = IMSUBa(m(r2, i), IMPRODUCTa(m(r1, i), max))
inm(r2, i) = IMSUBa(inm(r2, i), IMPRODUCTa(inm(r1, i), max))
Next
End If
Next
Next

IMINVERS = inm

End Function

投稿日時 - 2019-02-03 20:10:10

QNo.9584303

困ってます

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

>Public Function IMINVERS(a As Range) As Variant
> Dim n As Integer, n1 As Integer, n2 As Integer
> Dim r1 As Integer, r2 As Integer, c As Integer
> Dim max As Variant
> Dim i As Integer
> Dim m() As Variant
> Dim inm() As Variant
> Dim rr As Integer, cc As Integer
> Dim no As Integer, ex As Variant
> n1 = a.Rows.Count
> n2 = a.Columns.Count
> n = n1
> ReDim inm(1 To n1, 1 To n2)
> For rr = 1 To n1
> For cc = 1 To n2
> If rr <> cc Then inm(rr, cc) = 0 Else inm(rr, cc) = 1
> 'End If
> Next
> Next
↑下から4行分
If rr <> cc Then
inm(rr, cc) = 0
Else
inm(rr, cc) = 1
End If
Next
Next
このようになっていませんでしたか?
まずは、正しくコピーするようにしましょう
他にも数か所、有りそうです

投稿日時 - 2019-02-03 20:41:30

補足

早々のご教示ありがとうございます.
頂いたAの内容の確認には少し時間がかかりそうです.
しばらく時間をください.
(エクセルシートを添付できれば伝わりやすいのでしょうが)

投稿日時 - 2019-02-03 23:51:24

お礼

前回に続きご回答頂きありがとうございました.
確かにコピーミスがあり,また原文にも
"atpvbaen.xlam!・・・が
"atpvbaen.xla!・・・・・となっている誤りを見つけました.
ただ,これを修正しても行列計算結果が「#VALUE!」となってしまいます.
マクロの手順には誤りはないようです.もっと単純な問題かも知れません.
今後は,定義関数「IMMULT」に関する部分に絞って改めて原因を探ろうと思います.ありがとうございました!

投稿日時 - 2019-02-06 21:47:48

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

配列数式の確定がうまくいっていないのではないでしょうか。
配列数式を使用した関数はCTRL+SHIFT+ENTERで確定する必要があり、
その場合式全体が{}で囲われた形になります。
配列数式は下記を参照してください
http://infolib.lotus.com/resources/symphony/3.0.0/sym20abd014/ja_jp/text/scalc/01/04060107.html
セルに式を送っているところを{}で囲んだ値を送ってみて改善しないでしょうか。

投稿日時 - 2019-02-05 12:58:48

お礼

ご回答頂きありがとうございました.
配列関数の入力方法は,標準の組込み関数で確認しており問題ありません.
質問の内容にはコピーミスもあり,また原文にも
"atpvbaen.xlam!・・・が
"atpvbaen.xla!・・・・・となっている誤りもありました.
ただ,これを修正しても行列計算結果が「#VALUE!」となってしまいます.マクロの手順にも誤りはないようです.もっと単純な問題かも知れません.
今後は,定義関数「IMMULT」に関する部分に絞って改めて原因を探ろうと思います.ありがとうございました!

投稿日時 - 2019-02-06 21:56:21

ANo.3

【お詫び】nn = c1は問題ありません。

ただ、戻り値が設定されていないだけです。で、False が返ります。が、多分、それは織り込み済みかも知れません。ともかく、デバッグしても何らエラーは出ないってことは確かです。

投稿日時 - 2019-02-04 00:20:24

お礼

ご回答頂きありがとうございました.
コピーミスがあり,また原文にも
"atpvbaen.xlam!・・・が
"atpvbaen.xla!・・・・・となっている誤りを見つけました.
ただ,これを修正しても行列計算結果が「#VALUE!」となってしまいます.
マクロの手順を確認しましたが誤りはないようです.もっと単純な問題かも知れません.
今後は,定義関数「IMMULT」に関する部分に絞って改めて原因を探ろうと思います.ありがとうございました!

投稿日時 - 2019-02-06 21:51:41

ANo.2

Q、エクセルマクロで定義した関数が動かにのは?
A、もしかしたらバグが潜んでいるのでは・・・

 質問者が示した関数をコピペしてコンパイルしてみました。結果は、エラーは発生しませんでした。もちろん、End Ifは生かして・・・。

 で、コピペしたコードを清書する過程で気が付いたのですが、IMMULT()の戻り値の設定に誤りがありそうです。

 Exit Function の中途埋め込みは好みではないので、以下のように修正。すると、c1 = r2 の場合の処理に疑問点が浮上。

  nn=c1

 なんで、nn=c1 って一行があるんでしょうね。Exit するんだから何の意味もないですよね。で、このままじゃーIMMULT()の戻り値はFalse になるかもです。

 なお、If Then 文、For 文もちゃんと End If、Next に対応していました。コンパイルエラーは発生しませんでした。

Public Function IMMULT(a As Range, b As Range) As Variant
  Dim r1 As Integer
  ・・・・
  Dim mm() As Variant
  Dim returnValue As Variant

  r1 = a.Rows.Count
  ・・・・
  If (c1 = r2) Then
    nn = c1
    ' ***********************
    returnValue = ?????
    ' ***********************
  Else
    cr = r1
    cc = c2
    ReDim mm(1 To cr, 1 To cc)
    For r = 1 To cr
      For c = 1 To cc
        mm(r, c) = 0
        For n = 1 To nn
          ・・・・
        Next r
      Next c
Next r
    returnValue = mm
  End If
  IMMULT = returnValue
End Function

投稿日時 - 2019-02-03 21:45:26

補足

早々のご教示ありがとうございます.
頂いたAの内容の理解に私には少し時間がかかりそうです.
確認に時間をください.
(エクセルシートを添付できれば伝わりやすいのでしょうが)

投稿日時 - 2019-02-03 23:50:06

お礼

ご回答ありがとうございました!

投稿日時 - 2019-02-06 21:57:26

あなたにオススメの質問