Excelでユーザー定義関数の区別方法とは?

このQ&Aのポイント
  • Excelでユーザー定義関数を使っている際に、ユーザー定義関数とワークシート関数を区別する方法が知りたいです。
  • ユーザー定義関数を値に変換してブックを外部に配布したいときに、ユーザー定義関数を見つける方法を教えてください。
  • ユーザー定義関数を見つけるために、UsedRangeの大きさやユーザー定義関数の数が影響して時間がかかる問題を解決したいです。
回答を見る
  • ベストアンサー

ユーザー定義関数が入力されたセルを調べたい

Excel でユーザー定義関数を作成し、アドインにして仕事で使っています。 これらの関数を使用したブックを外部に配布する時にユーザー定義関数を値に変換してから配布したいのですが、ユーザー定義関数とワークシート関数の区別の方法が判りません(外部にアドインは配布しません)。 Dim r As Range Dim f As String For Each r In Activesheet.UsedRange If r.HasFormula Then f = r.Formula Do ' f がユーザー定義関数の一覧の中に見つかれば、セル r の色を変えてループ脱出 Loop End If Next という方法を試みましたが、UsedRange の大きさやユーザー定義関数の数が多いことも影響して結構な時間が掛かってしまいます。 ユーザー定義関数とワークシート関数を区別する方法があれば、Do~Loop を回さなくて済むので、時間短縮できるのではないかと考えています。 よろしくお願いします。

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

  • ベストアンサー
  • SI299792
  • ベストアンサー率48% (713/1473)
回答No.3

他の方が指摘した通り、SpecialCellsで数式の入ったセルだけに絞ると早くなります。 また、ループで回すより、 関数一覧のシートを作って、Vlookup で検索方法をTrueにすると、2分法での検索なので、早くなります。 「関数一覧」のA列に関数一覧を入れて、昇順に並べ替えます。 このプログラムはかんすうが3つになっています。関数の数に合わせて直して下さい。 関数がどのように入っているか判りません。とりあえず、関数が1番左にあり、 =Jibunnnokannsu(A) のような形だけとしました。 =Sin(Jibunnnokannsu(A)) の様に1番左に関数がない場合は反応しません。このようなものがあるなら、 RegExpなどで分割して1つづつ確認する必要があります。 ' Option Explicit ' Sub Macro1() '   Dim R As Range   Dim F As String   Dim Length As Integer   Dim Vlookup As String '   For Each R In Cells.SpecialCells(xlCellTypeFormulas)     F = R.Formula     Length = InStr(F, "(") - 2     F = Mid(F, 2, Length)     On Error Resume Next     Vlookup = WorksheetFunction.Vlookup(F, [関数一覧!A1:A3], 1)     On Error GoTo 0 '     If Vlookup = F Then       R.Interior.Color = vbRed     End If   Next R End Sub

masnoske
質問者

お礼

回答ありがとうございました。 なるほど,ワークシート関数を使うことでスピードアップするのですね. 自作関数の一覧は,すでにシートにありますので,VLOOKUP関数で対応することにします.

その他の回答 (2)

  • HohoPapa
  • ベストアンサー率65% (454/690)
回答No.2

セルには、 ユーザ定義関数と出来合いの関数を組み合わせた計算式 を埋めることができますので、 >ユーザー定義関数とワークシート関数の区別の方法が判りません おそらく、区別することはできないと思いますし ちょっと探して見ましたがなさそうです。 だとすると課題は、 do~loopの外側にあるのではなく内側になりましょう。 内側のコードがわからないので推測ですが 私なら、課題ユーザ定義関数群の名前に共通の プレフィックス(接頭辞)またはサフィックス(接尾辞)を設け 計算式の文字列にこれらが含まれるかどうかで判定します。

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

長年OKWAVEの質問を見ているが、珍しいタイプの質問ですね。 小生には、力足らずだと思いますが、現状での感想的内容ですが。 (1)システム的(MSが設けたレベル)に、VBAで選別する方法はないのでは。 エクセルのワークシート関数と同じ名前の関数名は、ユーザー関数では作れない(使えない)と思うので、この「関数の名称に頼って探す」、しか方法がないのでは。 (2)やはり仕事(個人利用を越えて)として、もし質問のニーズがあるなら、システムを作った時点で、エクセル利用のための「ノート」「メモ」を作るべきかと。そこにユーザー関数と意義と使い方(引数のこと等)記述しておく、ということ。 (一般にエクセルレベル以上のシステムを作った時(あるいは受託業者)は、ドキュメンテーションとして、紙やワード等やWEBで、資料を残す体制にするはず。エクセル・オンリーやフロム・エクセル止まりの人はこういう習慣は思わないだろうが。やはり必要で、そこに書き残すべきかと。) ーーー 微力ながら下記をやってみた。WEB記事のコードを一部利用。 標準モジュールに Sub 数式の入力されているセルを取得選択する() Dim y As Range On Error GoTo ErrHandl k = 1: l = 1 Dim rng As Range Set rng = Cells.SpecialCells(xlCellTypeFormulas) rng.Select '--- For Each cl In Selection 'MsgBox cl.Address & "=" & cl.Formula x = cl.Formula x = Replace(x, "=", "") p = InStr(x, "(") - 1 x = Mid(x, 1, p) 'Cells(k, "G") = x ' k = k + 1 '--- Set y = Range("G:G").Find(x) If y Is Nothing Then Cells(l, "H") = x l = l + 1 End If Next '-- Exit Sub ErrHandl: MsgBox "アクティブシートに数式の入力されたセルは存在しません。" Err.Clear End Sub これで全セルを総なめするのでなく、数式の入ったセルだけ問題にする。 どれだけ早くなるかわからないが。 G列に既存使用の関数名、H列に今回出現した関数名を表示。 ーー これで1シートで使っている関数名のリストはが出せる。 G列に、MSが作った、5-6百ある関数名がWEB記事にでも、網羅的にあればコピーできるが、見たことない、が。 代表的な(ユーザー定義以外のMSが作った関数のうち)100個か、加えて多少の関数名をG列にセットできれば、本件の役に立つのでは。 上記G列は、MSが作ったワークシート関数を1列に並べておく。100%質問のニーズに、完全でなくても、エクセル経験者なら、利用している関数名リストから、ユーザー関数を排除することは可能だろう。また使用せる番地もシートに作ることはたやすいと思う。 するとH列にそれ以外の関数名が出るので、ユーザー関数名かどうか、判断しやすいと思った。今回のシートで初めて使われたMSの関数も少数は混じるが。  ただし欠点があって、上記は、先頭の関数だけで、関数を組み合わている場合の第2以下の関数名は捉えてない。これが致命傷かも。=IF()関数なら()内の実質意味のある関数名は拾えてない。 ーー WEBに http://mt-soft.sakura.ne.jp/kyozai/excel_mid/150_macro/50_userfunction/index.html#ex-function ユーザー定義関数の作り方 という記事があって、 Description:= Category:= という説明がある。小生などは、ここまで設定して、ユーザー定義関数を使いこなして(他のユーザーに提供して使いやすくして)ないが、もし今後、そういうものを完備しておくと、ユーザー定義関数も、VBAの網に引っかかるかも(テストしてないし、どういうコードで拾えるかはわからず、夢想部分)。

masnoske
質問者

お礼

ご回答ありがとうございます。 作成したユーザー定義関数は、主に社内データベースからデータを参照する関数です。 関数にすることで、検索キーをセルに入れておけば、データベースから引き出せるというのがミソです。 社内で使っているだけなら問題ないのですが、作成したExcel資料を社外に配布する時に関数の結果を値にしておかないと、社外でエラーの嵐になってしまいます。ご指摘のマニュアル作成や使用者への指導は実施しておりますので、そちらの心配はありません。

関連するQ&A

  • ユーザー定義関数 アドイン

    ユーザー定義関数をアドインにどうやって保存するのでしょか? また、ユーザー定義関数以外のVBAをアドインに保存できますか?

  • EXCEl:ユーザー定義関数をLANで共有する方法

    LANに接続しているユーザーでVBAを共有する仕組みを以下のように構築しています。 == サーバー環境 == VBAはアドイン(Addin.xla)としてサーバー(\\SvA)に保存。 サーバーがもう1つあり(\\SvB)、Addin.xlaは、\\SvAから \\SvBに定期的にコピー。 \\SvAと \\SvBは、物理的に距離が離れているため、1つにできません。 == クライアント環境 == クライアントPCの XLSTARTフォルダには、Addin.xlaのショートカットを置く。 \\SvAのユーザーであれば、\\SvA\Addin.xlaへのショートカット、 \\SvBのユーザーであれば、\\SvB\Addin.xlaへのショートカットです。 Addin.xlaに変更があった場合に \\SvA\Addin.xlaを更新するだけなので、この方法を採用し、うまく運用できているのですが、ユーザー定義関数をワークシートで使用したいということになって、ハマってしまいました。 \\SvAのユーザーがユーザー定義関数 User1()をワークシートに =User1()と書き込んで他のユーザーにブックを配布しました。 \\SvAのユーザー間では問題なくブックを使用できますが、\\SvBのユーザーがそのブックを開くと 「このブックには、ほかのデータソースへのリンクが含まれています。」というメッセージが表示されます。 ここで、更新を選択すると、 「このブックには更新できないリンクが1つ以上含まれています。」というメッセージが表示されます。 ここで、継続を選択すると、 ユーザー定義関数が入力されたセルは #NAME? エラーが表示されます。\\SvBのユーザーのワークシートでは、ユーザー定義関数が ='\\SvA\Addin.xla'!User1()となっています。 この問題を解決する方法がないでしょうか。よろしくお願いいたします。

  • AccessVBAでユーザー定義関数使用

    エクセルVBAで、以下のユーザー定義関数(選択したセルaを全て3乗した和を求める)を使用していますが、アクセスVBAで同様の関数を使用するにはどうしたらよいでしょうか? ★アクセスVBVで実行したいプログラム 実行すると"データテーブル"の"Aフィールド"を全て3乗した和をmsgboxで表示 ★エクセルで使用していたユーザー定義関数 ’-------------------------------------- Function y(a As Range) As Variant Dim r As Range Dim result As Variant For Each r In a result = result + r.Value ^ 3 Next y = result End Function ’-------------------------------------- ぞうぞよろしくお願い致します。

  • ユーザー定義関数について質問します。

    他社からもらったエクセルファイルにユーザー定義関数が埋め込まれていました。 これが非常に使いやすく便利なのです。しかし、一部を修正したいところがあるのですが「ユーザー定義関数」について知識がありません。 勉強しようと思ってますが、とりあえずこの関数の定義内容を見てみたいのですが、どうすれば中身が確認できますか? アドイン関数ではないので関数の定義は当ファイル内にあるはずです。 よろしくお願いします。

  • VBAで書いたExcelユーザー定義関数が上手く動きません

    WinXPSP2 Office2003 を使用しています。 プログラムは、本やネットで調べただけの素人です。 具体的には、大量のascファイルにファイル自身の情報をヘッダとして書き込む作業をします。 そのために、ファイルの情報などを返すユーザー定義関数を作り、それを用いた一連の書き込み作業をマクロにして保存し、アドイン化してしまおうと考えました。 作業をマクロにしてアドイン化することはできるようになりましたが、肝心のユーザー定義関数を作るVBAが良くわかりません。 たとえば以下のように、ファイルの作成日時を返すユーザー定義関数を書いて標準モジュールに張ってみたのですが、上手く動きませんでした(具体的には”#VALUE!”になる)。 Function CreationDate() CreationDate = ActiveWorkbook.BuiltinDocumentProperties("Creation Date").Value End Function 次の、ファイルの名前を返すユーザー定義関数は上手く動きました。 Function FileName() As String FileName = Application.ActiveWorkbook.Name End Function なぜ後者が動いて前者が動かないのか、よく理解できません。 どのように変えればよいのか、教えていただけないでしょうか? よろしくお願いします。

  • ユーザー定義関数について

    ここで良いのかわかりませんが質問します。 現在、ExcelVBAをすこしかじりました。 ユーザー定義関数を作りましたが、第三者に簡単にわかるようにしたいと思います。fxボタンを押せばなんとなく第三者でもわかりそうですが、ボタンの存在を知らない人はわからないと思いました。 ワークシート上では直接関数を打てば、直下にコメントのようなスタイルでどの数値を入れればよいか出てくると思います。 =round( と打てば =round( (数値,桁数) というように出てくるのですが、ユーザー定義関数でこのようなことはできるのでしょうか? これが出来る出来ないでは第三者への進め方が大きく違ってきます。 教えてgooはもちろんいろいろ調べましたがわかりません。 何卒ご指導お願いします。

  • ユーザー定義関数をボタンに登録したい

    数式のエラーを回避するユーザー定義関数を作りPERSONAL.xlsに登録しました。 その後アドインに保存して、関数の挿入ダイアログボックスのユーザー定義関数から選んで使用していますが、頻繁に使用するのでボタンに登録したいのです。 どのようにすればいいのでしょうか? ネットで検索して色々やってみてるのですが分かりません。 ボタンのマクロの登録で「PERSONAL.xla!vlookupエラー回避」と直接打ち込んで登録してみましたが、実際にボタンをクリックすると「コンパイルエラー End Subが必要です」というエラーメッセージが出ます。 どこをどうすればいいのか教えてください。よろしくお願いします。 Sub vlookupエラー回避() ' ' vlookupエラー回避 Macro ' マクロ記録日 : 2006/7/25 ユーザー名 : ******** ' Function myVLookup(Rg As Range, Area As Range, col As Integer, opt As Integer) Dim vlk As Variant vlk = Application.VLookup(Rg, Area, col, opt) If IsError(vlk) Then vlk = "" End If myVLookup = vlk End Function

  • Excelのユーザー定義関数について。

    ネットで調べて「アルファベットのみを半角にする」というユーザー定義関数を発見し使用していますが、 この関数にある特定の文字を変換する条件を追加することはできますでしょうか。 例えば、リンゴ という文字がセル内にある場合、ミカン に変換されて表示されるという条件を下記のユーザー定義関数に加える事ができますか。 もしくは、新たに別のユーザー定義関数を作るしかないのでしょうか。アドバイスよろしくお願いします。m(_ _ )m Function ASC_A(str As String) As String Dim i As Integer For i = 1 To Len(str) If Mid(str, i, 1) Like "[a-zA-Z]" Then Mid(str, i, 1) = StrConv(Mid(str, i, 1), vbNarrow) End If Next ASC_A = str End Function

  • 【VBA】ユーザ定義関数が動かない

    【VBA】ユーザ定義関数が動かない 下記のようなプログラムをVBEの標準モジュールに記述して、 ワークシートの適当なセルに「=tc("aa","bb")」と入力してEnterを押した所 セルの表示が「=tc("aa","bb")」となってしまい狙った効果が得られません。 本当は、「aabb」と表示させたいのですが、なぜうまくいかないのでしょうか。 ご教授願います。 ◆関数の仕様  引数1と引数2に入力された文字列を連結して返り値として返す。 ◆コード Function tc(str1 As Range, str2 As Range) As String Dim Str As String Str = str1.Value & str2.Valuett tt = Str End Function

  • 関数の引数に複数のユーザ定義型変数を使いたい

    一つの関数の一つのパラメータが異なるユーザ定義型を受けられるようにしたいのですが、どのようにすればいいのでしょうか? Public Type TypeA strCodeA As String intNumA As Integer End Type Public Type TypeB strCodeB As String intNumB As Integer End Type Public Function funcTest(arg1 As Variant) As Integer (略) End Function と記述して関数を Dim datA As TypeA iResult = funcTest(datA) と呼び出そうとすると、次のようなエラーメッセージが表示されて進みません。 コンパイルエラー: パブリックオブジェクトモジュールで定義されたユーザー定義型に限り、変数に割り当てることができ、実行時バインディングの関数に渡すことができます。

専門家に質問してみよう