vba初心者です。(ネットからコードを拾ってきてちょっと改造できる程度)
excel 2003を使用しています。
【前提】
・「数式」「数値」「文字列」等がセルに入力されたエクセルファイルを使用する
⇒「関数名」のみを表示する。(文字列や数値が入力されたセルは無視)
・「数式」セルには「関数」が使われているものと、そうでないものがある
・1セル内に複数の関数が使用されている場合あり(新出の関数名であればすべて抽出したい)
・検索対象シート:ブック内のすべてのシート
【質問】
findメソッドで「IF」や「SUM」というように直接関数名を指定して検索するのではなく、「関数」というククリで検索はできるのでしょうか?
その検索結果を同ファイル内に新しいシート(Sheet1)を作成し、「関数名」を一覧表示するという流れ(以下にまとめました)にしたいです。
【手順】
(1)Book1内で「関数」検索をする
(2)「関数」が見つかった場合は「Sheet1」シートを作成(関数が見つからない場合は,msgbox "該当なし")
(3)検索した「関数名」をSheet1のA1セルに入力する
(4)Book1内すべて(複数シート有り)の関数名を抽出するまで連続検索をする
⇒A1→A2→A3→…の様に、A列の上から順に入力していく
※関数名の重複がないように一覧化できれば最高です。
※シート毎に、抽出した関数名を分けなくて大丈夫です。(あくまでファイル全体で使用されている関数名の一覧)
(5)msgbox "終了"
解決方法をご存知の方、ご教示願えませんでしょうか。
宜しくお願いいたします。
No.1
- 回答日時:
こんにちは。
数式をもったセルは SpecialCells で参照できます。
On Error Resume Next
' 23: xlErrors or xlLogical or xlNumbers or xlTextValues
Set rHasFormula = ActiveSheet.Cells. _
SpecialCells(xlCellTypeFormulas, 23)
On Error Goto 0
この結果、オブジェクト変数 rHasFormula が Nothing であれば、
「関数を使ったセルは無し」
とみなせます。あとは、数式をもったセル rHasFormula を For Each で
順次処理していくわけです。
数式から関数を抽出するには正規表現(RegExp)を使うのが楽でしょう。
このとき数式内の A1、B1 などのセル参照式はマッチングに都合が悪い
ですから、予め
s = Application.ConvertFormula(数式, xlA1, xlR1C1, xlRelative)
と相対参照の R1C1 形式に変換しておきます。これでセル参照文字は RC[]
といった自明の文字に固定できますから、除外し易くなりますよね。
マッチングパターンは、
reg.Pattern = "([a-zA-Z]+)" または
reg.Pattern = "([^!-@\[\]]+)"
とかでしょうか、、工夫してみて下さい。
重複なしのリストは、Scripting.Dictionary を使います。
No.2
- 回答日時:
何を関数とするかが難しそうですね。
アドインで使用できる関数は増やせますし、ユーザ関数も作れます。
こんなのはどうでしょう。
予めSheet1を追加して、A列に検索したい関数一覧を入れておきます。
Excel標準で使用できる関数一覧ならネットでいくらでも見つかりますからそこからコピペで……。それ以外の関数は地道に入力。
その上で、下記のマクロで検索。使用している関数の隣に1が入ります。
但し、このマクロは不完全です。関数名+「(」の有無で検索していますが、例えばセル式が「TODAY()」の場合、TODAYでもDAYでもカウントしてしまいます。
この辺りは正規表現をうまく使えば何とかなりそうな気がします。
Sub SampleMacro1()
Dim countsheet As String
Dim ws As Worksheet
countsheet = "Sheet1" '<-- 集計シート名
Application.ScreenUpdating = False
For Each ws In Worksheets
If ws.Name <> countsheet Then
Call SelectFormula(ws, countsheet)
End If
Next
Worksheets(countsheet).Select
Application.ScreenUpdating = True
MsgBox "終了"
End Sub
Sub SelectFormula(wws As Worksheet, wCountsheet As String)
Dim rng As Range
Dim targetRange As Range
On Error GoTo Errtrap
'数式セルのみ選択、数式セルが無い場合はErrTrapへ
Set targetRange = wws.Cells.SpecialCells(xlCellTypeFormulas, 23)
For Each rng In targetRange
'- Sheet1 A列の関数一覧との比較
For i = 1 To Worksheets(wCountsheet).Range("A65536").End(xlUp).Row
rtn = InStr(rng.Formula, Worksheets(wCountsheet).Cells(i, 1) & "(")
'-- 使用されている関数があればB列に1をたてる
If rtn > 0 Then
Worksheets(wCountsheet).Cells(i, 2) = 1
End If
Next i
Next
Errtrap:
End Sub
mt2008 さん
ご回答ありがとうございます。
お礼が遅くなってしまってすみません。
コードを読み解くのに時間が掛ってしまいました…
> 何を関数とするかが難しそうですね。
そうなんです。散々考えてアイディアが浮かびませんでした…
> Excel標準で使用できる関数一覧ならネットでいくらでも見つかりますからそこからコピペで……。それ以外の関数は地道に入力。
私も最初は、すべての関数を検索すれば良いかなっと思っていたのですが、網羅するのが難しいなと。
今回検索対象となるファイルが約800あるのですが、全ファイルのユーザー関数を地道に抽出するのは大変そうです。(ユーザー関数が使用されているかも今確認できません)
でも全関数の一覧ができれば、'- Sheet1 A列の関数一覧との比較 でうまいことフラグが立ちますね。(自分で適当にファイルを作成して試してみました。)
自分なりに対応策を考えてみます。
マクロを組んで頂きありがとうございます。
勉強になりました。とても感謝しています。
No.3ベストアンサー
- 回答日時:
#1 です。
なんか質問の形式をとった作成依頼っぽい気がしなくもない。一応
突っ込み入れときます。
こんな感じでできる気がする。適当に参照設定をして試してみて下さい。
ユーザー定義関数(日本語名を含む)があっても大丈夫かと。
余談:
vArray = Range("A1:C1").Formula
で Value 同様数式の2次元配列が得られますから、速度面が問題になる
ようなら配列処理に改造してみて。
Sub sample()
Dim dic As Dictionary
Dim reg As RegExp
Dim regMatch As Match
Dim s As String
Dim rHasFormula As Range
Dim r As Range
Dim sh As Worksheet
Set reg = New RegExp
Set dic = New Dictionary
reg.Global = True
reg.Pattern = "([^!-@\[\]]+)"
For Each sh In ActiveWorkbook.Worksheets
Do
On Error Resume Next
' 23: xlErrors or xlLogical or xlNumbers or xlTextValues
Set rHasFormula = sh.Cells. _
SpecialCells(xlCellTypeFormulas, 23)
On Error GoTo 0
If rHasFormula Is Nothing Then Exit Do
For Each r In rHasFormula.Cells
' // 数式のセル参照文字をR1C1相対参照に固定する
s = Application.ConvertFormula(r.Formula, _
xlA1, _
xlR1C1, _
xlRelative)
For Each regMatch In reg.Execute(s)
Select Case UCase$(regMatch.Value)
' // セル参照文字やブール値を除外
Case "R", "C", "RC", "TRUE", "FALSE"
Case Else
' // Dictionary でカウントしつつ重複のないリストにする
dic(regMatch.Value) = dic(regMatch.Value) + 1
End Select
Next
Next
Exit Do
Loop
Next sh
' // 出力(面倒なので適当)
With ThisWorkbook.Worksheets("Result")
.Activate
.Cells.Delete
With .Range("A1:B1")
.Font.Bold = True
.Value = Array("Function", "Count")
End With
.Range("A2").Resize(dic.Count).Value = Application.Transpose(dic.Keys)
.Range("B2").Resize(dic.Count).Value = Application.Transpose(dic.Items)
.Columns("A:B").AutoFit
End With
Set reg = Nothing
Set dic = Nothing
End Sub
KenKen_SP さん
ご回答ありがとうございます。
お礼が遅くなってごめんなさい。
作成までしていただいてありがとうございます。
実は#1のご回答を基に作成していたところ、自分の知識ではうまくいかず途方にくれていました…
#3でご回答いただいたコードを実行した結果、ほぼ私の意図通りの処理内容でした。
超感謝しています。ありがとうございました。
しかし、関数の中身で別ファイルのセルを参照していると"Result"シートの"function"列に意図しない文字列が抽出されるのです。
具体的には…
数式:=CONCATENATE([ジャンル.xlsx]Sheet1!$D$2,'[問題集.xlsx]Sheet2(2)'!$A$1)
"function"列
CONCATENATE
ジャンル
xlsx
Sheet
問題集
という感じです。
もれなくすべての関数名を抽出できていますし、「意図しない文字列」は目視でも確認できるのですが、ちょっと気になって。
正直、KenKen_SPさんのコードもまだ完全には解析できていないので、vbaの勉強も兼ねて上記問題を解決できるように考えてみます。
お手数お掛けしてすみませんでした。
本当に助かりました。ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 顧客ごとに違う点検案内を作成するマクロ 4 2022/09/16 05:34
- Visual Basic(VBA) VBA 検索と入力 Excel ブック ぶぶぶ シート ししし 列V 検索対象の列です 最終行は、お 6 2023/05/17 01:40
- Excel(エクセル) VLOOKUP が機能しない、その原因は何 ? 8 2022/10/19 12:06
- Visual Basic(VBA) vbaエクセルマクロ RemoveDuplicatesについて RemoveDuplicatesを使 3 2023/02/28 01:13
- Excel(エクセル) ユーザー定義について質問です。 2 2023/06/28 13:21
- Excel(エクセル) エクセルで”入力シート”の文字書式の変更を”出力シート”で同じ文字書式で印刷したいです。VBA希望 4 2023/04/24 11:07
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Excel(エクセル) エクセル関数の変わった使い方 3 2022/05/13 17:12
- Visual Basic(VBA) VBA 改行コードの取り方 1 2022/03/22 14:14
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ExcelVBAを使って、値...
-
特定のセルが空白だったら、そ...
-
【Excel VBA】指定行以降をクリ...
-
Excelで指定した日付から過去の...
-
i=cells(Rows.Count, 1)とi=cel...
-
【Excel】指定したセルの名前で...
-
DataGridViewのセル編集完了後...
-
特定行の色を変えたい(FlexGrid)
-
VBAの計算で@が出てしまう件
-
Excelのプルダウンで2列分の情...
-
excelで置換をしたいんですが
-
エクセルvba:自己セルの情報取...
-
EXCELで変数をペーストしたい
-
【EXCEL VBA】Range("A:A").Fi...
-
3桁または4桁の数値を時刻に...
-
セル色なしの行一括削除
-
VBAでマクロ実行中はExcelのマ...
-
VBAでセルをクリックする回...
-
Excel VBA、 別ブックの最終行...
-
ExcelのVBAで数字と文字列をマ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ExcelVBAを使って、値...
-
特定のセルが空白だったら、そ...
-
【Excel VBA】指定行以降をクリ...
-
i=cells(Rows.Count, 1)とi=cel...
-
【Excel】指定したセルの名前で...
-
Excelで指定した日付から過去の...
-
特定の文字を条件に行挿入とそ...
-
Excel VBA、 別ブックの最終行...
-
EXCELで変数をペーストしたい
-
Excelのプルダウンで2列分の情...
-
Excel vbaで特定の文字以外が入...
-
TODAY()で設定したセルの日付...
-
screenupdatingが機能しなくて...
-
DataGridViewの各セル幅を自由...
-
Sub 要具ライフ() ActiveSheet....
-
【EXCEL VBA】Range("A:A").Fi...
-
VBAを使用した時間管理
-
VBAでセルをクリックする回...
-
セル色なしの行一括削除
-
エクセルVBAでコピーして順...
おすすめ情報