Excel2003でstring型のデータの所定文字数の数を取得する方法

このQ&Aのポイント
  • Excel2003のVBA関数を使用して、string型のデータで特定の文字の出現回数を取得する方法について質問があります。例えば、特定の文字列内に存在するカンマの数を取得する方法を知りたいです。2次元配列要素を1次元で一時格納し、それを再度2次元に格納する際にカンマの数を数える必要があるため、処理をスムーズに行いたいです。
  • 例えば、string型のデータがmyDataに格納されています。このデータ内のカンマの数を取得したいとします。
  • 質問者は、データが変更されるたびにカンマの数を数えて配列を再宣言するのが面倒であり、どれだけの数のカンマがあっても2次元に再格納できるようにしたいと考えています。具体的な方法を教えてください。
回答を見る
  • ベストアンサー

エクセル2003 string型のデーターの所定文字数の数の取得

いつもアドバイス頂きありがとうございます。 今回、質問させていただきたいのは、 string型でデーターを取得した文字列に対して ある文字の文字数がいくつ在るかを取得したいのですが VBA関数で、そのような関数はあるのでしょうか? 例  myDataにstring型の文字列を取得してあります。 その中に「,」(カンマ)が何個存在するかと言う事 を取得したい。 やりたい事として、mydata()の中に2次元配列要素となるデーターを 1次元で仮格納してあり、それをセルに書き出すために2次元 に格納(splitで再格納)しなおしているのですが、データーが変わる たびに、カンマの数を数えて配列宣言を記入するのが面倒なので、 カンマの数がいくつでも、2次元に再格納できるようにしたいためで す。 宜しくお願いいたします。

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

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんばんは。 >dim mydata(20000, 10) as Variant >と言う形等で、配列数を多く宣言しておけばいいのでしょうが、 >このやり方って空のデーターの箱を沢山作ってしまいっているので >なんかもったいないなと思って動的配列で宣言しております。 私は、他の言語を勉強したときに、なぜ、VBAやVBでは、そういう仕方をしないのかなって思ったことがあります。たぶん、根本的に、VBAやVB は、速度が遅いのが原因ではないか、と思います。それに、Ubound で上限が取れないので、配列の代入時に、カウントして、それを元にする、というしかないわけです。 >Find関数を用いて、条件を満たした行の必要な列をカンマで結合して格納してく方法を用いてます。 似たようにことを、私も以前やったような覚えがあります。 動的な2次元配列が、VBAの上級文法の最後のひとつに入りますね。上級とはいっても、必要不可欠です。 Excelでは、有名な「バブルソート・アルゴリズム」をExcelシートに応用するという命題みたいなものがあります。一応、掲示板の常連さんは、みなさん、一度は勉強していると思います。(偉そうな言い方で申し訳ないのですが。) とはいえ、なぜ、Excelにとって、2次元配列がややこしいかというと、お気づきだと思いますが、排出の仕方が、縦横逆になるからなのです。For Each ~ in myRange でやってみると、左から右へと動いていくのが分かりますが、配列は、添え字の1次側から順に排出てしていきます。ちょっと不思議ですよね。たぶん、これは、メモリの確保の仕方から来るものだと思います。 また、2次元の場合は、二次側を、動的配列にします。一次側は固定されます。 Redim Preserve myData(固定値, カウンター) それから、 WorksheetFunction.Transpose これは、1次元に限ります。ただ、こういうレベルというのは、このサンプルで見たとおり、そのままですから、 Worksheets("Sheet2").Range("A1"). _  Resize(UBound(myData, 1) + 1, UBound(myData, 2) + 1).Value = myData() で、形どおりに貼り付けが可能です。 ----------------------------------------------------------- 先ほどからずっと、動的2次元配列のサンプルが思いつきませんので、#1さんの補足に書かれたものを元に書いてみました。一般的には、配列に配列を入れるようなことはしないで、そのまま、1行ずつ排出します。 なお、余計なことかもしれませんが、私個人は、  Option Base 1 を使わないことにしています。将来的になくなるということもありますが、今回のコードの場合は、逆にややこしくなっているようです。配列は、0からスタートと考えていたほうが安全です。 ためしに、入れ替えてみました。以下のコードのように、Max で、上限を取らざるを得ません。それ以外に、列幅の上限を知る方法はありません。通常は、一行ずつ処理するというのが一般的です。ここまですると、ややこしいです。 'Option Explicit Option Base 1 Sub ArrayTest()   Dim buf As Variant   Dim Max As Integer   Dim i As Long   Dim j As Long   Dim k As Long   Dim v As Variant   Dim myData(10)   Dim myAray() As Variant   Dim OutPutData() As Variant      myData(1) = "あ,い,う,え,お" 'ここの列数は不明ゆえ   myData(2) = "か,き,く,け,こ" 'Max を取る   myData(3) = "さ,し,す,せ,そ"   myData(4) = "た,ち,つ,て,と"      For i = 1 To UBound(myData)   If myData(i) = Empty Then Exit For     buf = Split(myData(i), ",")     ReDim Preserve myAray(1, i) '動的2次元配列     '配列をチェックしないと、エラーが出る     If IsArray(buf) Then     If (UBound(buf) + 1) > Max Then Max = (UBound(buf) + 1)     End If     myAray(1, i) = buf   Next i   ReDim OutPutData(i - 1, Max)   For j = 1 To i - 1     For Each v In myAray(1, j)       k = k + 1       OutPutData(j, k) = v     Next v     k = 0   Next j   Range("A1").Resize(UBound(OutPutData(), 1), UBound(OutPutData(), 2)).Value _    = OutPutData() End Sub 何かのヒントになった幸いです。

tmgolf
質問者

お礼

お返事ありがとうございます。 このような形でテストサンプルコードまで ご用意頂き誠にありがとうございます。 VBAを勉強させていただくに当たり、このような サンプルコード等を頂け誠にありがとうございます。 こういった形でコード読んでいきますと、自分の 理解できていなかった事や、コードの記述テクニック等 色々な面で勉強させていただけるので、とても 助かります。おかげさまでVBAを勉強始めてから 仕事の能率がかなりはかどっているしだいです。 誠にありがとうございます。 今後ともご質問させていただく機会はあると思いますが 宜しくお願いいたします。

その他の回答 (2)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

こんばんは。 言葉で説明されても、私は、あまり理解力がないせいか良く分からないですね。 私自身は、本来は、全体的なものを見て判断したいですね。 2次元配列と1次元配列を行き来するということは、通常はしません。モーグの有名な方は、そういうテクニックを公開していますが、まず、私は、そういうことには直面しません。 通常は、2次元は、最初から、2次元のまま処理するのが普通だと思います。 ただし、CSVなどは、1次元で行ごとに処理します。 String型で入手したものは、 Dim myStr As String Dim i As Long Dim j As Long  myStr = "a,b,c,d,e"  i = Len(myStr) - Len(Replace(myStr, ",", ""))  j = UBound(Split(myStr, ",")) このどちらかになりますが、状況によっては、「i」側は、区切り文字が、TextCompare が選べる利点があります。なお、正規表現は、私は、この種類には使いません。理由は、遅いからです。

tmgolf
質問者

お礼

お返事ありがとうございます。 Len関数とreplace関数でこのような形で得られるのですね。 それと、jの取得の仕方。まるっきり気がつきませんでした。 ありがとうございます。 余談なのですが) <<通常は、2次元は、最初から、2次元のまま処理するのが普通だと思います。 2次元で格納していくスキルが無いため、無理やり1次元で仮格納して 2次元にしてセルに書き出すやり方をしております。 Find関数を用いて、条件を満たした行の必要な列をカンマで結合して 格納してく方法を用いてます。 最初に dim mydata(20000, 10) as Variant と言う形等で、配列数を多く宣言しておけばいいのでしょうが、 このやり方って空のデーターの箱を沢山作ってしまいっているので なんかもったいないなと思って動的配列で宣言しております。 そうすると、どうしてもRedim Preserveで1次元目を宣言しなおせ ないので1次元で必要な列データをカンマで結合して格納していって いるしだいです。 書き出しの時に WorksheetFunction.Transpose を上手く使えば2次元の要素を増やしていく格納のやり方とか 出来そうな気がするのですが、自分の頭の中が混乱してくるのと Transposeの使い方が理解できていないため、 2次元で格納→2次元で書き出し を行わず 1次元で格納→2次元で書き出し と言う処理にしております。 余談終了) wendy02様にはいつもご丁寧なアドバイス、ご回答をいただき誠に ありがとうございます。

  • hana-hana3
  • ベストアンサー率31% (4940/15541)
回答No.1

Split()関数でデータを分割する事が可能ですよ。 Ubound()関数で配列の要素数を取得する事が出来ます。 Split関数で文字列を区切る http://officetanaka.net/excel/vba/tips/tips62.htm

tmgolf
質問者

補足

すみません。上手く説明が出来ていませんでした。 mydata(1)="あ,い,う,え,お" mydata(2) ="か,き,く,け,こ"  ・  ・ と言う風に、mydata()の中にstringデーターが格納されている とします。 Option Base 1 Dim OutPutData As Variant Private Sub データー再格納() Dim myAry As Variant   Dim a As Integer, b As Integer ReDim OutPutData(uboun(mydata), 5)<<<<(*) For a = LBound(mydata) To UBound(mydata) myAry = Split(mydata(a), ",") ReDim Preserve myAry(UBound(myAry) + 1) For b =LBound(myAry) to UBound(myAry) OutPutData(a,b) = myAry(b) Next b Next a End Sub (*)のところの「5」と言う数字をmydata(1)の文字列から取得する関数 と言うものが存在するのでしょうか? カンマの数が数えられれば、その数プラス1で取得できればと考えた のですが。 InStr関数をループで用いれば、取得できそうなのですが、特定の 文字をカウントする関数などあればと思い、ご質問させていただきました。

関連するQ&A

  • 文字数を取得したい

    漢字を含んだ文字列の文字数を取得したのですがうまくいきません。 どなたか教えてください。 例: 「asetg漢字」という文字列だったら、7文字として取得したい。 上記の例で、lstrlenや、MFCの関数(String)で文字数の取得を試みたのですが、バイト数で取得してしまうため、うまくいきませんでした。

  • 文字列の取得(BCB6.0)

    初歩的な質問なのですが・・・ テキストファイルから文字列を配列に格納したいです。 テキストファイルからTStringListには取得できているようなのですが。。。 テキストファイルの形式が 文字1 OFF、文字1 ON 文字2 OFF、文字2 ON     … となっており、コンマで区切って2次元配列に格納したいです。 どなたか宜しくお願い致します。 auto_ptr<TStringList> xSList(new TStringList()); xSList->LoadFromFile("D:\\sample.txt"); for(int i=0; i<=xSList->Count; i++) { AnsiString str = xSList->Strings[i];     …(ここで2次元配列に格納したい)

  • C# Splitと配列の複合方法

    こんにちは、 ”てすと、です。¥四月、寒い。” のような文字列があり これを¥で区切り、さらにカンマで区切って(Splitでここはできたのですが) 結果を下記のように配列に格納したいと思うのですが、どのように記述すればよいでしょうか? 配列(0,0)=”てすと” 配列(0,1)=”です。” 配列(1,0)=”四月” 配列(1,1)=”寒い。” 文字列の内容が定まっていないため配列の要素数が変動してするものでして。

  • VBA、Excel、文字列の置換について

    エクセルのVBAを勉強しているものなのですが 行き詰ってしまったので有識者の方、アドバイスをお願いします 目的:セルに入力されているカンマで区切られた文字列(例、1,2,5,6,7,8,10,11・・・)で連番の場合間の数字を"-"で省略(例、1,2,5-8,10,11・・・)する関数の作成 以下、プログラム (1)カンマで区切られた文字列をスプリットし、配列化 For Each cl In moji myData = Split(cl, ",") Next (2)3つ以上の連番の場合、"-"で文字列の短縮化 For l = 1 To UBound(myData) If myData(l) = myData(l + 1) - 1 Then If myData(l) = myData(l - 1) + 1 Then myData(l) = "-" ElseIf myData(l) = "-" Then myData(l) = "" Else myData(l) = myData(l) & "," End If Else myData(l) = myData(l) & "," End If Next l (3)配列をカンマで区切られた文字列として出力 For m = 0 To UBound(myData) bunkai = bunkai & myData(m) Next m

  • Excel(VBA)で配列の要素数を調べるには?

    お世話になります。 ExcelのVBAで、split関数を使って配列に格納したデータの要素数を調べる方法がわかりません。 下記のようなコードで、読み込んだデータを配列(Arraydata)に格納することは出来たのですが、test.csvの要素数が処理の度に変わるため、要素数に応じて後続の処理を行ないたいと考えています。 Open test.csv For Input As #1 ' test.csvファイルを開く Line Input #1, test.csv ' データ行を読み込む Arraydata = Array(Split(test.csv, ",")) ' 配列に格納 よろしくお願いします。

  • 特定のフィールドの文字列を取得

    初心者ですがよろしくお願い致します。 □わからない事 ・特定のフィールドの文字列を取得 ・取得した文字列を配列に格納 □条件 ・mysqlにはすでにデータが登録済み ・PHPより操作 □具体例 フィールド名(hogehoge)に文字列が入っています。 AAAAAA(10000レコード) BBBBBB(5000レコード) CCCCCC(3000レコード) DDDDDD(1000レコード) ・・・・・・(・・・・レコード) 重複が多数ありますが、重複しない文字列だけを取り出して配列に格納したいと思っていますが、うまいやり方がわかりません。 どなたか教えて頂けませんか? よろしくお願い致します。

    • ベストアンサー
    • MySQL
  • ArrayIndexOutOfBoundsExceptionの対処法

    jspで下記のようにStringの文字列をsplitによって Stringの配列に格納しています。 文字列strは"文字,文字" か "文字," か ",文字" という感じで格納されています。 String str; String[] str.split(","); そしてjspでString[0]とString[1]を必ず表示するようになってます。 そうすると文字列"文字,"の場合はString[1]は存在しないため 例外がでて怒られてしまいます。 文字列は入力値のため、どの文字列のパターンが来るか分からない ためどうすればいいのか分からず困っています。 いい方法があればあれば教えていただければと思います。

    • ベストアンサー
    • Java
  • 文字取得

    教えてください! fgetsでストリームから文字をline[20]に格納できたとします。 その後、lineから1文字づつ参照していき、 カンマで区切られたデータをそれぞれ別の変数に格納したいのです。 1文字づつ参照するためにはどんな関数でできますか? getcやfgetcではできないと思うのですが・・・。

  • C# 文字列の分割

    VS2005を使用しているものです。 複数のURL(入力)を格納したString型の配列があるのですが、 この配列から各要素(URL)の最後尾にあるファイル名だけを 取り出して別のString型の配列に入れたいのですが Splitなどを駆使すればよいのでしょうか? 例 C:\○○○\▲▲▲\××.拡張子 (元の配列の要素の一例)   などから××.拡張子の文字列だけを取り出して   別の配列に格納する感じです。 splitを使う際は\などを区切りに考えています。 for文の中でsplitを駆使しようと考えたのですが、分割した文字列を別で配列に格納して、その最後尾の要素だけ取り出したいのですが、URLの長さは入力によってまちまちなのでどのようにして取り出せばよいか困っています。 勉強不足で恐れ入りますが、何かご教授願えれば幸いです。

  • EXCEL VBA 2次元配列に格納された値の最小値を調べたい

    いつもお世話になっております。 ブックAのマクロからブックBのデータを以下のように配列に入力しています。 myData = Workbooks("ブックB.xls").Worksheets("temp").Range("A1:G1000") 配列myDataに格納された値の最小値を調べたいのですが、myDataに格納されているデータは数値だけではなく、日付、時間も含まれます。 数値のみが含まれるのはmyDataの3~6列です。 myDataが数値のみの配列の場合、 WorksheetFunction.Min(myData) で配列全体を調べることが出来るのは分かったのですが、今回の場合は日付、時間が含まれるため「型が一致しません」というエラーがでて、最小値を求めることが出来ませんでした。 WorksheetFunction.Minを使って特定の列(今回の場合3~6列)に格納されている数値の最小値を調べることは出来るのでしょうか。 3~6列を別の配列に格納すればそれで解決なのですが、出来れば変数をmyDataだけで済ませたいと思っています。 また、WorksheetFunction.Minを使わないでfor文を使う方法も考えつきましたが、できればWorksheetFunction.Minなどの関数を使ってスマートにやりたいと思っています。 よろしくお願いします。

専門家に質問してみよう