advanced help
per page, with , order by , clip by
Results of 1 - 1 of about 37697 for IF (0.007 sec.)
[[20230522142756]]
#score: 1591
@digest: daa4248be20bd6d7798166d357eff62c
@id: 94305
@mdate: 2023-05-27T00:35:02Z
@size: 28261
@type: text/plain
#keywords: breakbracket (344960), inputstring (253909), openparenthesis (143198), extractkatuko (111293), closeparenthesis (109022), wfbreakbracket2 (88570), depth (83473), getinparentheses (74983), {[ (43943), wfbreakbracket (42959), 【< (39040), ({ (32048), 高価 (27247), submatches (16554), optional (16262), bs (14719), ッコ (14265), コ内 (14261), (教 (13069), function (9517), 再帰 (8889), カッ (8868), strconv (8289), vbtab (7816), ・ω (6628), ・` (6385), 2023 (6325), mid (5162), 汎用 (4927), pattern (4736), split (4727), 全角 (4716)
『文字列内のカッコ内の文字列を抽出する』(教えてくん)
ExcelのVBAで文字列中のカッコ内の文字列を抽出する関数を作成したいと思います 但し条件として文字列中にカッコが複数ある場合は、先頭から何番目のカッコ内の文字列を抽出するかを指定できる仕様としました。 最下部のコードで処理できたので 更なる改造で大文字と小文字のカッコの両方に対応したいと思いますがどのようにコードを変更したらいいですか ? Option Explicit Function Extractkatuko(ByVal inputString As String, ByVal index As Integer) As String Dim openParenthesis As Integer Dim closeParenthesis As Integer Dim i As Integer Dim count As Integer openParenthesis = 0 closeParenthesis = 0 count = 0 For i = 1 To Len(inputString) If Mid(inputString, i, 1) = "(" Or Mid(inputString, i, 1) = ")" Then If Mid(inputString, i, 1) = "(" Then openParenthesis = i Else closeParenthesis = i End If If openParenthesis <> 0 And closeParenthesis <> 0 Then count = count + 1 If count = index Then Extractkatuko = Mid(inputString, openParenthesis + 1, closeParenthesis - openParenthesis - 1) Exit Function End If openParenthesis = 0 closeParenthesis = 0 End If End If Next i End Function < 使用 Excel:Excel2021、使用 OS:Windows11 > ---- カッコを大文字か小文字かに統一(置換)してから 処理、でいかがでしょう? (MK) 2023/05/22(月) 14:32:09 ---- 正規表現を使う、という方法もあります。 私自身は正規表現に精通してないので解説できませんが。 https://vbabeginner.net/extract-all-strings-in-parentheses/ (MK) 2023/05/22(月) 15:16:07 ---- カッコが「()」(小文字)と「( )」(大文字)専用の Extractkatuko_bigとExtractkatuko_smallの2つのコードならすぐに出来たのですが 汎用がつまずいています。 カッコを小文字かに統一(置換)すれば処理できるのは気が付いていましたが せっかくなら汎用のコードにしたいです。 (教えてくん) 2023/05/22(月) 15:16:52 ---- ですから、コード中で置換してはいかが?という 意味だったのですが。 (MK) 2023/05/22(月) 15:20:42 ---- 参考HPです。 http://officetanaka.net/excel/vba/function/strconv.htm (MK) 2023/05/22(月) 15:22:23 ---- StrConvは文字列全体が置換されますので、 Replaceでカッコのみを置換したほうがよかった ですね。 (MK) 2023/05/22(月) 15:24:22 ---- Replaceした後の文字列をSplit関数で 「(」で区切ってさらに「)」で区切ると()の中 を取得出来ます。 まどろっこしい方法ですが。 (MK) 2023/05/22(月) 15:27:06 ---- >>コード中で置換してはいかが?という意味だったのですが。 ありがとうございます。 なるほど、考え違いしていました。 下記のようなコードと言うことでしょうか? 不具合あれば修正してください。 Function Extractkatuko(ByVal inputString As String, ByVal index As Integer) As String Dim openParenthesis As Integer Dim closeParenthesis As Integer Dim i As Integer Dim count As Integer openParenthesis = 0 closeParenthesis = 0 count = 0 'ReplaceBrackets 'コード中で全角のカッコがあれば半角に変換置換 Dim str As String Dim ii As Long str = inputString For ii = 1 To Len(str) If Mid(str, ii, 1) = "(" Then Mid(str, ii, 1) = "(" ElseIf Mid(str, ii, 1) = ")" Then Mid(str, ii, 1) = ")" End If Next ii inputString = str '処理 For i = 1 To Len(inputString) If Mid(inputString, i, 1) = "(" Or Mid(inputString, i, 1) = ")" Then If Mid(inputString, i, 1) = "(" Then openParenthesis = i Else closeParenthesis = i End If If openParenthesis <> 0 And closeParenthesis <> 0 Then count = count + 1 If count = index Then Extractkatuko_small = Mid(inputString, openParenthesis + 1, closeParenthesis - openParenthesis - 1) Exit Function End If openParenthesis = 0 closeParenthesis = 0 End If End If Next i End Function (教えてくん) 2023/05/22(月) 15:37:12 ---- > Extractkatuko_small = Mid(inputString, openParenthesis + 1, closeParenthesis - openParenthesis - 1) ↓ですね。ここを修正したら他は問題ないです。 Extractkatukol = Mid(inputString, openParenthesis + 1, closeParenthesis - openParenthesis - 1) 元のコードを一部修正した場いいです。 StrConvを使ってます。 If Mid(inputString, i, 1) = "(" Or Mid(inputString, i, 1) = ")" Then If Mid(inputString, i, 1) = "(" Then ↓ If StrConv(Mid(inputString, i, 1), 8) = "(" Or StrConv(Mid(inputString, i, 1), 8) = ")" Then If StrConv(Mid(inputString, i, 1), 8) = "(" Then (MK) 2023/05/22(月) 15:50:11 ---- inputString = Replace( str, "(","(") inputString = Replace( inputString , ")",")") でどうでしょうか? (QS) 2023/05/22(月) 16:22:35 ---- 別案ですが、 Option Compare Text をモジュールの冒頭に宣言しておけば、テキストモードでの比較になりますので、全角と半角を区別しません。 ですので、最初のコードでご希望の動作になります。 Option Explicit Option Compare Text Function Extractkatuko(ByVal inputString As String, ByVal index As Integer) As String 以下略 (hatena) 2023/05/22(月) 16:28:08 ---- ちなみに、Split関数を使えば、下記で同様の結果になります。 Option Explicit Option Compare Text Function Extractkatuko(ByVal inputString As String, ByVal index As Integer) As String On Error Resume Next Dim ary ary = Split(inputString, "(") Extractkatuko = Split(ary(index), ")")(0) End Function (hatena) 2023/05/22(月) 16:42:11 ---- MKさん、アドバイスありがとうございます。 StrConv(を追加したほうは良いとの事ですが 最初の無い場合と違いで有利な点は何ですか ? QSさん、アドバイスにあるコードの方が短くて直感で理解できます 'コード中で全角のカッコがあれば半角に変換置換 inputString = Replace(inputString, "(", "(") inputString = Replace(inputString, ")", ")") hatenaさん、ありがとうございます。 以下の事で理解が深まりました。 Option Compare Text をモジュールの冒頭に宣言しておけば、テキストモードでの比較になりますので、全角と半角を区別しません。 16:42のコードは、私にはまだまだ理解できるレベルを超えています。 すばらしい。 '--------------------- (教えてくん) 2023/05/22(月) 16:44:17 ---- 正規表現でーと思ったけど、なんか不可解な動きが・・・ Function GetInParentheses(words As String, Optional idx As Long = 1) As String Dim re As Object: Set re = CreateObject("VBScript.RegEXP") Dim m As Object re.Global = True '全角()通しか半角()通しの最短一致の組み合わせを探す 're.Pattern = "¥(.*?¥)" re.Pattern = "¥(.*?¥)|(.*?)" Set m = re.Execute(words) If m.Count > 0 And m.Count >= idx Then idx = idx - 1 '組み合わせがわかったら、()の中身をSubmatchesに入れるため、パターンを定義しなおす re.Pattern = "(¥(|()(.*?)(¥)|))" Set m = re.Execute(m(idx)) GetInParentheses = m(0).submatches(1) End If End Function Sub test() Dim a As String a = "123(456)789,987(654)321,ABC(DEF)GHI,JKL(MNO)PQR" Debug.Print "1 = "; GetInParentheses(a, 1) Debug.Print "2 = "; GetInParentheses(a, 2) Debug.Print "3 = "; GetInParentheses(a, 3) End Sub 半角全角区別するつもりで書いたハズなんですが、3番目が想定外・・・なんでだろう? 1 = 456 2 = 654 3 = DEF → DEF)GHI,JKL(MNO になる予定だった 他人のスレでございますが、どなたかわかります・・・? (稲葉) 2023/05/22(月) 16:54:58 ---- > 16:42のコードは、私にはまだまだ理解できるレベルを超えています。 やっていることは、それほど難しいことではありません。(配列が理解できてないと難しいか?) MsgBox Extractkatuko("AA(BB)CC(DD)EE",2) というコードを実行したとします。 ary = Split(inputString, "(") で文字列を"("で区切った配列にしてaryに代入します。 aryには下記のような ["AA", "BB)CC", "DD)EE"] という3分割された配列が代入されます。 Splitの配列のインデックスは0から始まりますので、 ary(0)は"AA" ary(1)は"BB)CC" ary(2)は"DD)EE" となります。 Extractkatuko = Split(ary(index), ")")(0) はindexが2なので、ary(index)は "DD)EE" となります。 これを Split で ")" で分割した配列["DD","EE"]にして、 その先頭の "DD" を取り出して、Extractkatuko に代入してます。 (hatena) 2023/05/22(月) 17:18:06 ---- > If StrConv(Mid(inputString, i, 1), 8) = "(" Or StrConv(Mid(inputString, i, 1), 8) = ")" Then >StrConv(Mid(inputString, i, 1), 8) = "(" Mid(inputString, i, 1)で取得した文字列 を半角に変換した文字列をStrConv(変換前文字列, 8) で半角に変換した文字列が半角左カッコ"("だったら となります。 最初にカッコをReplaceで半角に変換しておけば StrConv の出る幕はなくなります。 (MK) 2023/05/22(月) 17:22:35 ---- ↑の私のレスは >StrConv(を追加したほうは良いとの事ですが > 最初の無い場合と違いで有利な点は何ですか ? に対するものです。 (MK) 2023/05/22(月) 17:23:36 ---- 稲葉さんの発言へのコメントです。前後の文脈を理解していませんが、こういうことでしょうか。 If m.Count > 0 And m.Count >= idx Then idx = idx - 1 '組み合わせがわかったら、()の中身をSubmatchesに入れるため、パターンを定義しなおす '' re.Pattern = "(¥(|()(.*?)(¥)|))" re.Pattern = "¥((.*?)¥)|((.*?))" Set m = re.Execute(m(idx)) ''GetInParentheses = m(0).submatches(1) GetInParentheses = m(0).submatches(0) & m(0).submatches(1) End If # ===== 以下、 5/23 追記 ================= 理由は、半角カッコ と全角カッコで囲まれたものも許しているからでしょうね。 よくよく見たら、2段階にしなくてもよかったかもしれません。 Function GetInParentheses(words As String, Optional idx As Long = 1) As String Dim re As Object: Set re = CreateObject("VBScript.RegEXP") Dim m As Object re.Global = True '全角()通しか半角()通しの最短一致の組み合わせを探す re.Pattern = "¥((.*?)¥)|((.*?))" Set m = re.Execute(words) If m.Count > 0 And m.Count >= idx Then idx = idx - 1 GetInParentheses = m(idx).submatches(0) & m(idx).submatches(1) End If End Function (xyz) 2023/05/22(月) 18:21:45 ---- ちなみに入れ子になったものは正規表現でも解析できなかったと思います。 スキルの問題ではなく正規表現自体の持つ限界によるものです。 (xyz) 2023/05/22(月) 18:57:42 ---- Splitを使った方法で、Option Compare Text を宣言しない場合のコード例 Function Extractkatuko(ByVal inputString As String, ByVal index As Integer) As String On Error Resume Next Dim ary ary = Split(inputString, "(", index + 1, vbTextCompare) Extractkatuko = Split(ary(index), ")", index + 1, vbTextCompare)(0) End Function 引数に vbTextCompare を設定することでテキストモードの比較になります。 (hatena) 2023/05/22(月) 19:09:15 ---- MKさん、ありがとうございます。 考え違いをしていました。 (StrConv(は、最初にカッコをReplaceで半角に変換しておけば必要ない) hatenaさん、コードの解説ありがとうございます。 配列が理解できていないので解説があると助かります。 とりあえずコードは完成したので indexで指定した数値が存在しない場合のエラー処理を考えてみました。 (「Extractkatuko」を「カッコ内文字抽出」に変名しています。) If count = index Then カッコ内文字抽出 = Mid(inputString, openParenthesis + 1, closeParenthesis - openParenthesis - 1) Exit Function Else If count <> index Then カッコ内文字抽出 = "「順番の指定」が変です。" End If これで十分なのか確信が持てません。 不具合や修正(これも必要等)あれば教えてください。 (教えてくん) 2023/05/23(火) 05:55:27 ---- xyzさん ありがとうございました。 二階建てにしたために、()と()を区別して抽出したのに、最短一致になってしまったわけですね・・・ > re.Pattern = "(¥(|()(.*?)(¥)|))" re.Pattern = "(¥(|()(.*)(¥)|))" 最短一致を最長一致にして希望の取れました。 > re.Pattern = "¥((.*?)¥)|((.*?))" > GetInParentheses = m(idx).submatches(0) & m(idx).submatches(1) こちらの組み合わせもありがとうございました! (稲葉) 2023/05/23(火) 08:29:06 ---- 面白そうだったのでつくってみました。 あまり参考にならないですが。 BreakBracket関数は与えた文字列をタブ区切りで分解するので、 BreakBracket関数の返値をSplit関数でvbTabで区切れば任意の順番の文字列が得られます 最外側のカッコしか対応してないので、入れ子のときは、さらに繰り返し関数にいれてやらないといけません 入れ子になってるときの順番はどう数えればいいんでしょう? Sub sample() Dim s As String s = "+++(aa)+(bb)+(cc)+(dd)+++" s = BreakBracket(s) Debug.Print s printary Split(s, vbTab) s = "(aa)+(bb)+[cc]+<dd>+「ee」+(ff)+『gg』+{hh}" s = BreakBracket(s, "(({{[【<「『") Debug.Print s printary Split(s, vbTab) End Sub Sub printary(ByVal ary) Dim i As Long, c i = 1 For Each c In ary Debug.Print i; c i = i + 1 Next End Sub Function BreakBracket(ByVal s, Optional ByVal bs As String = "(") Dim p As Long, depth As Long Dim be As String If s = "" Then Exit Function be = bs For p = 1 To Len(be) Mid(be, p, 1) = Chr(Asc(Mid(bs, p, 1)) + IIf(Mid(bs, p, 1) Like "[[{<]", 2, 1)) Next p = 1 Do While p <= Len(s) If InStr(1, bs, Mid(s, p, 1)) Then Exit Do p = p + 1 Loop If p > Len(s) Then Exit Function s = Mid(s, p + 1) depth = 1 p = 1 Do While p <= Len(s) If InStr(1, bs, Mid(s, p, 1)) Then depth = depth + 1 If InStr(1, be, Mid(s, p, 1)) Then depth = depth - 1 If depth = 0 Then Exit Do p = p + 1 Loop If depth > 0 Then Exit Function BreakBracket = Left(s, p - 1) & vbTab & BreakBracket(Mid(s, p + 1), bs) If Right(BreakBracket, 1) = vbTab Then BreakBracket = Left(BreakBracket, Len(BreakBracket) - 1) End Function (´・ω・`) 2023/05/23(火) 16:33:39 ---- ´・ω・`さんのコードをお借りして Functionを改造しようとしましたが「#Value!」のエラーが出てしまいます。 アクティブセルに配列としてにタブで区切られた文字列が複数記録されているので アクティブセル内の配列を文字列を左から順番に取り出して右方向のセルに全て表示する事としたいのですが どこを修正すれば良いですか? 例えば、 A4セルに "123(456)789,987(654)321,ABC(DEF)GHI,JKL(MNO)PQR" を入力 B4セルに BreakBracket(A4) と関数を入れると 以下のように出力させたい B4セル 456 C4セル 654 D4セル DEF E4セル MNO もしくは C4セル 456 D4セル 654 E4セル DEF F4セル MNO Function BreakBracket(ByVal s, Optional ByVal bs As String = "(({{[【<「『") Dim p As Long, depth As Long Dim be As String Dim tmp As Variant Dim i As Long, ii As Long If s = "" Then Exit Function be = bs For p = 1 To Len(be) Mid(be, p, 1) = Chr(Asc(Mid(bs, p, 1)) + IIf(Mid(bs, p, 1) Like "[[{<]", 2, 1)) Next p = 1 Do While p <= Len(s) If InStr(1, bs, Mid(s, p, 1)) Then Exit Do p = p + 1 Loop If p > Len(s) Then Exit Function s = Mid(s, p + 1) depth = 1 p = 1 Do While p <= Len(s) If InStr(1, bs, Mid(s, p, 1)) Then depth = depth + 1 If InStr(1, be, Mid(s, p, 1)) Then depth = depth - 1 If depth = 0 Then Exit Do p = p + 1 Loop If depth > 0 Then Exit Function BreakBracket = Left(s, p - 1) & vbTab & BreakBracket(Mid(s, p + 1), bs) If Right(BreakBracket, 1) = vbTab Then BreakBracket = Left(BreakBracket, Len(BreakBracket) - 1) arr = Split(BreakBracket, vbTab) For ii = LBound(arr) To UBound(arr) ActiveCell.Offset(0, ii + 1).Value = arr(ii) Next ii End Function (教えてくん) 2023/05/24(水) 06:19:53 ---- BreakBracket関数は編集しないで、ワークシート関数用の別の関数でラッピングするのがいいです Function wfBreakBracket(ByVal s, Optional ByVal bs As String = "(") wfBreakBracket = Split(BreakBracket(s, bs), vbTab) End Function として、=wfBreakBracket(A4,"((") をB4に入力 (´・ω・`) 2023/05/24(水) 07:18:59 ---- ´・ω・`さん、ありがとうございます。 教えてもらったコードで複数カッコ内の文字列が抽出できました。 (教えてくん) 2023/05/24(水) 11:14:44 ---- ものすっごい今更で申し訳ないんですが 過去の投稿でこんなのがありました。 参考にどうぞ。 [[20220729101019]] (傘) 2023/05/24(水) 16:50:07 ---- お願いします。 wfBreakBracketのfunctionを少し改造して汎用にしたいので以下のように考えましたが indexを指定しないで=wfBreakBracket2(A4)などとすると「#VALUE!」のエラーがでます。 (=wfBreakBracket2(A4,2)などindexを指定した場合は処理されています。) indexを指定しない場合は、どのように改変すれば良いですか? (すなおにindexを指定する必要がない場合は、wfBreakBracketを利用すれば良いのでしょうが勉強のための相談です。) Function wfBreakBracket2(ByVal s, index, Optional ByVal bs As String = "(({{[【<「『") Dim arr() As String Dim maxarr As Single arr = Split(BreakBracket(s, bs), vbTab) maxarr = UBound(arr) - LBound(arr) + 1 If index = "" Then wfBreakBracket2 = Split(BreakBracket(s, bs), vbTab) Else If index > maxarr Then wfBreakBracket2 = "Errror : 指定個数が不正です。" Else wfBreakBracket2 = arr(index - 1) End If End If End Function (教えてくん) 2023/05/25(木) 13:11:32 ---- Optionalの意味をVBAのヘルプで確認されたらいかがですか? 当該ヘルプの記事の最後に例が載っています。 なお、よく読んでいませんが、BreakBracket(s, bs)は再帰を使った割と高価な処理なので、 そう何度も実行させないほうが良いと思います。 (xyz) 2023/05/25(木) 13:47:32 ---- xyzさん、アドバイスありがたいのですが 悲しいかなさっぱり理解できていません。 >Optionalの意味をVBAのヘルプで確認されたらいかがですか? >当該ヘルプの記事の最後に例が載っています。 具体的にどこを参照すれば良いのか?良くわかりません。 >割と高価な処理なので、 >そう何度も実行させないほうが良いと思います。 VBA素人が免罪符にはならないでしょうが、 何が「高価」なのか意味がわかりません。 この「高価」とは、どういう意味ですか ? なんども実行させると不具合がでるとの意味で複数回の実行を否定させているのはなぜですか ? (教えてくん) 2023/05/25(木) 14:34:07 ---- ここ読んでください。 https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/function-statement >この「高価」とは、どういう意味ですか? 一言でいえば「重たい」です 今回は面倒だったので、再帰にしましたが、具体的には ・再帰のために、同じ処理を必要もないのに繰り返している →例えば指定された括弧"("と同じ閉じ括弧")"を呼び出しの度に毎回求めるようになっていて無駄 ・再帰呼び出しのため、メモリのスタック領域を多く使う →再帰を使わないで書いた方が、PC資源の節約になります。 といった感じ そのほか、出来る節約はしたほうがいいです。 arr = Split(BreakBracket(s, bs), vbTab) と一回求めているので、 wfBreakBracket2 = Split(BreakBracket(s, bs), vbTab) も wfBreakBracket2 = arr と書けるハズ (´・ω・`) 2023/05/25(木) 15:49:09 ---- ´・ω・`さん、アドバイスありがとうございます。 教えてもらったURLから派生した以下のURLが私には参考になりました。 (MSのURLは私にはわかりにくい) VBA 省略可能な引数 Optional と名前付き引数 https://www.tipsfound.com/vba/02022 xyzさんの言いたいであろう「高価」の意味は理解できました。 つまり、再起呼び出しを利用しているので多用するとPCのメモリーを消費するし 処理が遅く(重く)なると言う事ですね。 (汎用を目指して、Optional ByVal bs As String = "(({{[【<「『")としているので 使用されていないカッコも処理する事になり無駄が多い) indexの初期値まず指定しない値 0(ゼロ) にセットして以下のようにして見ました。 問題あればアドバイスお願いします。 (指摘された無駄なコードは修正済みです。) Function wfBreakBracket2(ByVal s, Optional Index As Integer = 0, Optional ByVal bs As String = "(({{[【<「『") Dim arr() As String Dim maxarr As Single arr = Split(BreakBracket(s, bs), vbTab) maxarr = UBound(arr) - LBound(arr) + 1 If Index = 0 Then wfBreakBracket2 = arr Else If Index > maxarr Then wfBreakBracket2 = "Errror : 指定個数が不正です。" Else wfBreakBracket2 = arr(Index - 1) End If End If End Function (教えてくん) 2023/05/25(木) 16:15:39 ---- ・ワークシートから直接呼べるようにしました ・再帰じゃなくループで書き直しました。 ・省略可能な引数indexで順番を指定できるようにしました Function BreakBracket(ByVal s, Optional index As Long = 0, Optional ByVal bs As String = "(") Dim p As Long, depth As Long Dim be As String Dim buf() As String, i As Long If s = "" Then Exit Function be = bs For p = 1 To Len(be) Mid(be, p, 1) = Chr(Asc(Mid(bs, p, 1)) + IIf(Mid(bs, p, 1) Like "[[{<]", 2, 1)) Next ReDim buf(1 To Len(s) ¥ 2) i = 0 Do While s <> "" p = 1 Do While p <= Len(s) If InStr(1, bs, Mid(s, p, 1)) Then Exit Do p = p + 1 Loop If p > Len(s) Then Exit Function s = Mid(s, p + 1) depth = 1 p = 1 Do While p <= Len(s) If InStr(1, bs, Mid(s, p, 1)) Then depth = depth + 1 If InStr(1, be, Mid(s, p, 1)) Then depth = depth - 1 If depth = 0 Then Exit Do p = p + 1 Loop If depth > 0 Then Exit Do i = i + 1 buf(i) = Left(s, p - 1) s = Mid(s, p + 1) If i = index Then Exit Do Loop If index = 0 Then ReDim Preserve buf(1 To i) BreakBracket = buf Else If index <= i Then BreakBracket = buf(index) Else BreakBracket = CVErr(xlErrNA) End If End If End Function (´・ω・`) 2023/05/25(木) 17:25:36 ---- (´・ω・`)さん、汎用にできるコード変更にアドバイスいただきありがとうございます。 A1にtestDATAを記載して asdf gh(123) jklh_ghu (78945) fgh B1に =BreakBracket(A1,1)、=BreakBracket(A1,2)を入れると 正解が抽出さますが B1に =BreakBracket(A1)でindexを指定しない場合 「123」 と 「78945」 の2つがスピルされて表示されるハズが 「0」と表示されてしまします。 (=BreakBracket(A1,3)の場合も「0」が表示される。) 改造された =BreakBracket だけで処理が完結するのではなく 前と同じく wfBreakBracketから呼び出す操作が必要ですか ? そうだとするとBreakBracketのパラメーターで Optional index As Long = 0 をわざわざ指定したのはなぜか ? ずっと考えましたが解決しません。 (教えてくん) 2023/05/26(金) 11:57:52 ---- たぶん、私のミスなのでちょっとお待ちください (´・ω・`) 2023/05/26(金) 12:15:02 ---- こちらです。 Function BreakBracket(ByVal s, Optional index As Long = 0, Optional ByVal bs As String = "(") Dim p As Long, depth As Long Dim be As String Dim buf() As String, i As Long If s = "" Then Exit Function be = bs For p = 1 To Len(be) Mid(be, p, 1) = Chr(Asc(Mid(bs, p, 1)) + IIf(Mid(bs, p, 1) Like "[[{<]", 2, 1)) Next ReDim buf(1 To Len(s) ¥ 2) i = 0 Do While s <> "" p = 1 Do While p <= Len(s) If InStr(1, bs, Mid(s, p, 1)) Then Exit Do p = p + 1 Loop If p > Len(s) Then Exit Do ' <=== ここ Exit Functionを Exit Do に修正 s = Mid(s, p + 1) depth = 1 p = 1 Do While p <= Len(s) If InStr(1, bs, Mid(s, p, 1)) Then depth = depth + 1 If InStr(1, be, Mid(s, p, 1)) Then depth = depth - 1 If depth = 0 Then Exit Do p = p + 1 Loop If depth > 0 Then Exit Do i = i + 1 buf(i) = Left(s, p - 1) s = Mid(s, p + 1) If i = index Then Exit Do Loop If index = 0 Then ReDim Preserve buf(1 To i) BreakBracket = buf Else If index <= i Then BreakBracket = buf(index) Else BreakBracket = CVErr(xlErrNA) End If End If End Function (´・ω・`) 2023/05/26(金) 13:07:51 ---- ´・ω・`さん、変更されたコードありがとうございます。 以下は、コードを試した結果です。 asdf gh(123) jklh_ghu (78945) fgh 123 =BreakBracket(A1,1) ---> 1 #N/A =BreakBracket(A1,2) ---> 2 123 =BreakBracket(A1) ---> 3 #NAME? =BrakeBracket(A1,"(") --> 4 2) 全角カッコの場合処理できていません。 3)Indexが無い場合、スピルされて全て抽出されるはずですがされていません。 4) bsとして全角カッコを指定した結果です。 [[{<] の部分の指定に問題があるのかと (({{[【<「『 に変更してみました。 コードを以下に変更してみました。 Function BreakBracket(ByVal s, Optional index As Long = 0, Optional ByVal bs As String = "(({{[【<「『") Mid(be, p, 1) = Chr(Asc(Mid(bs, p, 1)) + IIf(Mid(bs, p, 1) Like "(({{[【<「『", 2, 1)) 以下は、コードを試した結果です。 asdf gh(123) jklh_ghu (78945) fgh 123 =BreakBracket(A1,1) 78945 =BreakBracket(A1,2) #スピル! =BreakBracket(A1) #NAME? =BrakeBracket(A1,"(") (教えてくん) 2023/05/26(金) 14:41:04 ---- 関数の呼び出し方の問題でしょう 規定のかっこは半角の(だけなので、全角(は明示的に指定しないとだめです また 2番目の引数はindexで、3番目の引数が括弧です =BreakBracket(A1,1,"((") ' indexが 1、 括弧は (( 全角と半角 =BreakBracket(A1,2,"((") ' indexが 2、 括弧は (( 全角と半角 =BreakBracket(A1,,"((") ' indexは省略、括弧は (( 全角と半角 (´・ω・`) 2023/05/26(金) 16:30:04 ---- indexを指定しない場合は、(A1,, のように指定しなければならず 私の想定した =BreakBracket(A1) ---> 3 のような書き方はダメなのですね。 >規定のかっこは半角の(だけなので、全角(は明示的に指定しないとだめです そうだと思ったので汎用(万能)を目指して使われるであろう全角を含むカッコを 以下を対象にしたく "(({{[【<「『" コードを以下のように書き換えていますが Function BreakBracket(ByVal s, Optional index As Long = 0, Optional ByVal bs As String = "(({{[【<「『") Mid(be, p, 1) = Chr(Asc(Mid(bs, p, 1)) + IIf(Mid(bs, p, 1) Like "(({{[【<「『", 2, 1)) ちゃんとどんなカッコを検索するのか3番目の引数で明示しないと抽出対象にならないのですね 関数の呼び出し方が想定していたのと違う事が理解できました。 (教えてくん) 2023/05/26(金) 18:38:43 ---- >Mid(be, p, 1) = Chr(Asc(Mid(bs, p, 1)) + IIf(Mid(bs, p, 1) Like "(({{[【<「『", 2, 1)) こここは改変しちゃだめです。 理由は、beの中身を確認したら分かります (´・ω・`) 2023/05/26(金) 18:55:50 ---- なんどもありがとうございます。 新しいコードのBreakBracket関数は、前の同名の関数と 使い方が違うように思えるので使い分ける事にします。 個人的には、=wfBreakBracke(A1)だけでスピルされて表示される以前の関数の方が好みです。 (教えてくん) 2023/05/27(土) 09:09:39 ---- >使い方が違うように思える あなたがIndexの引数を増やしたから変わったんで... (´・ω・`) 2023/05/27(土) 09:35:02 ...
https://www.excel.studio-kazu.jp/wiki/kazuwiki/202305/20230522142756.txt - [detail] - similar
PREV NEXT
Powered by Hyper Estraier 1.4.13, with 97062 documents and 608326 words.

訪問者:カウンタValid HTML 4.01 Transitional