配列の値を保持しながら要素を追加する方法は?

このQ&Aのポイント
  • 配列の値を保持しながら要素を追加する方法についてご質問です。
  • 通信データを処理するプログラムを作成している際に、配列に値を追加する方法についてお悩みです。
  • また、配列の最後の2つの要素を保持しながら、次に来たデータを配列に追加する方法についてもお教えいただきたいです。
回答を見る
  • ベストアンサー

配列の値を保持しながら要素を追加するには

通信データを処理するプログラムを作っています 変数strDataにCR区切りのデータがいくつか(個数はそのつど変わります)文字列として入って送られてきて、 それを配列strData1()に入れて、たとえば strData1(r)=strData1(r+1)+strData1(r+2)+strData1(r+3) のような計算をしようと思っています。 strData1 = Split(strData, vbCr) For r = 0 To Ubound(strData)-2 strData1(r) = (CDbl(strData1(r)) + CDbl(strData1(r + 1)) + CDbl(strData1(r + 2)) Next r とすると、配列の最後の2つの要素は何も出てきませんよね。 なので、最後の2つのデータを保持しながら、次に来たstrDataを配列にいれて、For文の計算に戻すことをしたい、 また、strDataが3個以下の場合も考えると、ある一定個数をためてから一気に計算させたほうがいいのかとも思いますが、 For文が終わるとまたすぐに一行目を実行して上書きされてしまうようで、うまい方法がわかりません。 なにかヒントになりそうな考え方だけでもいいので、ご助言お願いします。

  • chr02
  • お礼率50% (3/6)

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

  • ベストアンサー
回答No.4

すみません、#3 の >(1) r = 0 の処理 >(2) r = 1 の処理 >(3) For r = 2 To UBound(strData1) - 2 は間違いです。 (1) 保存した strData1(n-2) の計算 (2) 保存した strData1(n-1) の計算 (3) For r = 0 To UBound(strData1) - 2 ということです。 つまり、 Private Sub Pool(ByVal strData As String)   Dim strData1() As String   Dim i As Integer   Dim n As Integer   Static vPrev1 As Variant   Static vPrev2 As Variant   strData1 = Split(strData, vbCr)   If Not IsNull(vPrev1) Then     vPrev1 = vPrev1 + vPrev2 + strData1(0)     vPrev2 = vPrev2 + strData1(0) + strData1(1)   End If   For i = 0 To UBound(strData1) - 2     strData1(i) = strData1(i) + strData1(i + 1) + strData1(i + 2)   Next i   n = UBound(strData1)   vPrev1 = strData1(n - 1)   vPrev2 = strData1(n) End Sub のような感じです。 初期化されていない Variant は IsNull(v) = True になるのかどうかは、ちょっと自信なしです。

chr02
質問者

お礼

モジュール変数にして試したところ、うまくいきました。 ありがとうございました!

その他の回答 (3)

回答No.3

1回目のstrData → strData1(0),strData1(1),strData1(2) 2回目のstrData → strData1(3),strData1(4),strData1(5),strData1(6) ... N回目のstrData → strData1(r),strData1(r+1),strData1(r+2),...,strData1(n) これら、strData1(0) ~ strData1(n) に対して For i = 0 To UBound(strData1) - 2   strData1(i) = strData1(i) + strData1(i+1) + strData1(i+2) Next i を計算したい、ということですね? やり方としては、strData が全て送られてくるまでためておいて、最後にまとめて処理するのが簡単だとは思いますけど。 ↓こんな感じで・・・。 Private strData1() As String Private Sub Form_Load()   ReDim strData1(0) End Sub 'strData を CR で分割して strData1 に蓄積する。 '注意:strData1(1) から埋められていきます。 Private Sub Pool(ByVal strData As String)   Dim strTemp() As String   Dim iStart As Integer   Dim i As Integer   iStart = UBound(strData1) + 1   strTemp = Split(strData, vbCr)   ReDim Preserve strData1(iStart + UBound(strTemp))   For i = 0 To UBound(strTemp)     strData1(iStart + i) = strTemp(i)   Next i End Sub 送られてくるデータの数が非常に多いとか、通信処理のタイミングの関係で、全て溜めてから処理することができないのであれば、 strData1(UBound(strData1)-2)、strData1(UBound(strData1)-1) をモジュール変数か Static 変数に保存しておいて、 For r = 0 To UBound(strData1) - 2 を (1) r = 0 の処理 (2) r = 1 の処理 (3) For r = 2 To UBound(strData1) - 2 に三つに分割するくらいしかないと思います。

回答No.2

すみません、やりたいことがもう一つはっきりわからないので質問させてください。 >変数strDataにCR区切りのデータがいくつか(個数はそのつど変わります)文字列として入って送られてきて、 >それを配列strData1()に入れて ここまではわかるのですが、 >strData1(r)=strData1(r+1)+strData1(r+2)+strData1(r+3) のところがよくわかりません。 要は、strData1(0)+strData1(1)+...+strData1(n) を計算したいということなのでしょうか? それでしたら Dim v As Variable v = 0 For i = 0 To UBound(strData1)   v = v + strData1(i) Next i のような感じで計算できると思うのですが、やっぱりそういうことではないのでしょうね・・・。

chr02
質問者

補足

すいません、確かに判りづらいですね。 要はフィルタとしてn個(質問では3個にしましたが)の加算平均をやりたいのですが、 送られてくるデータが一度に1~30個位のバラバラなデータなので、 送られてきたデータのみでn個の加算平均をすると、データの後ろからn個部分の配列は捨てなくてはなりませんよね。 そのためうまくいっていないようで、 それを防ぐために捨てる部分が無視できるくらいためてから計算するのがよいのかなと思ってますが、 こんな方法のほうがもっといいんじゃないか、というのがあれば、宜しければ教えてください

  • todo36
  • ベストアンサー率58% (728/1234)
回答No.1

ReDim Preserve

chr02
質問者

補足

これを使えという意味ですか? 値が100こになるまでデータを配列にいれるつもりで Do strData1 = split(strData , Vbcr) ReDim preserve strData1(UBound(strData1)) Loop Until UBound(strData1)>100 としたんですが、当たり前ですがフリーズしました。 もうひとつ配列を作ってそこに足しこんでいくほうがいいんですかね

関連するQ&A

  • 動的配列の後始末?

    以下のサブルーチンで、lines()と動的配列を定義して、Splitでデータを入れたのですが、このサブルーチンが終了すると、lines()はデータも含めて解放されるのでしょうか? 極端な話、1億回このサブルーチンを呼ぶと、メモリーリークするのでしょうか? それと、VB6やVB.NETでは、For文・For Each文のどちらを使う方が良いのでしょうか? Sub test() Dim lines() As String lines = Split(Data, vbCrLf, -1, vbBinaryCompare) Dim i As Integer For i = LBound(lines) To UBound(lines) MsgBox ("for=[" & lines(i) & "]") Next i Dim s As Variant For Each s In lines MsgBox ("for each=[" & s & "]") Next End Sub

  • 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, ",")) ' 配列に格納 よろしくお願いします。

  • EXCEL VBA(2003) での積上グラフの要素の合計表示について

    縦積上グラフの合計値をデータラベルの形で既存のグラフに表示するマクロを作成しました。 現状では行方向に県名(要素)、列方向に男/女人口(系列)を並べ、女人口の隣の列に各県の男女の合算人口を並べて”1”で参照させています(データラベルにしたいのでValueをTEXT値にしています)。 マクロでは、既存グラフの要素数を取得して、同数の要素(値は全てゼロ)をもつ配列を新系列に加え、上でTEXT化した合計値をデータラベルの.TEXTに設定するという方法をとっています。 現状の行列の配置の場合には下のマクロが期待通りの実行結果を返してくれますが、既存グラフのデータ範囲の設定で行/列の向きを逆にし、性別毎の合計値を①で参照させた場合には”2”のように要素数と”1”で取得したデータ数が一致しないという結果が返ります。 ”3”付近で間違いをしている気もするのですが、どなたかご指摘いただけますと幸甚です。 Sub Test() Dim newRange As Range Dim newSC As Variant ' Σ系列の配列変数 Dim SCcnt As Integer ' SeriesCollectionの変数 Dim SC1Value As Variant ' SeriesCollection(1)の配列 Dim i As Integer Dim A1 As String 'A1形式→R1C1形式の変換に使用 Dim R1 As String 'A1形式→R1C1形式の変換に使用 Dim R1withSheetname As String 'A1形式→R1C1形式の変換に使用 Set newRange = Application.InputBox(Prompt:="合計欄の参照を選択してください。", Type:=8) '”1” newSC = newRange With ActiveChart SCcnt = .SeriesCollection.Count SC1Value = .SeriesCollection(1).Values '要素数を取得 '”3” If UBound(newSC) <> UBound(SC1Value) Then '”2” MsgBox ("(注意)選択したデータの個数が系列1のデータ個数と不一致。" & vbCr & vbCr & _ "選択範囲のデータ個数:" & (UBound(newSC) - LBound(newSC)) & vbCr & vbCr & _ "系列1のデータ個数:" & UBound(SC1Value)) End If .SeriesCollection.NewSeries SCcnt = SCcnt + 1 With .SeriesCollection(SCcnt) .Values = newSC .Name = "Σ" End With .PlotArea.Select .ApplyDataLabels AutoText:=True, ShowValue:=True For i = 1 To UBound(newSC) '系列数を取得 'R1C1形式に変換 A1 = newRange(i).Address R1 = Application.ConvertFormula(Formula:=A1, _ fromReferenceStyle:=xlA1, _ toReferenceStyle:=xlR1C1, ToAbsolute:=xlAbsolute) R1withSheetname = "=" & ActiveSheet.Name & "!" & R1 With .SeriesCollection(SCcnt) .DataLabels.Select .Points(i).DataLabel.Select With Selection .Text = R1withSheetname .Position = xlLabelPositionInsideBase End With End With Next i End With End Sub

  • 配列について。

    Redim した後   For i LBound(配列) To UBound(配列)    作業   Next i をしているのですが、配列の要素数を別プロセスで 計算させる場合、必ずしも要素が存在するとはかぎ りません。 その場合エラーがでるわけですが、このように配列 の中身が存在しない場合はどのように回避できるの でしょうか? VB6&Windows2000です。

  • エクセルVBAで配列の追加

    エクセル2000です。 1行4列のセル範囲のデータを配列に取り込んで、後から別の1行4列のセル範囲のデータを配列に追加し、2次元配列として吐き出そうと思います。 最初の範囲がA1:D1、追加範囲がA4:D4とした場合、こんな不細工なコードになってしまいました。 これでも動きますが、どう修正すべきでしょうか? Sub test() Dim myAr() myAr = Application.Transpose(Range("A1:D1").Value) ReDim Preserve myAr(1 To 4, 1 To 2) For i = 1 To 4 myAr(i, 2) = Cells(4, i) Next i Range("F1").Resize(UBound(myAr, 2), UBound(myAr, 1)).Value = Application.Transpose(myAr) End Sub

  • VBの配列 IsNull, IsNuthing, ...? 用途がわかりません。

    以下の場合、(1)で範囲エラーとなります。 redim a(0)とすると、a配列に1個データがあるということで、for文が実行されますが。 Redimしないまま(データが無い意味としたいので)で、このFor文をパスするには、どのように記述すればよいのでしょうか? dim a() as string '----->(2) for i=LBound(a) to UBound(a) '---->(1) msgbox(a(i)) next i

  • 重複データの表示

    教えてください。 ASP(クライアント側)の一部分です。 5件目にエクセルで表示したい列(A~Z)が入っています。 例えばDataの中身は 1: 001,aaa,111,bba,A,1 2: 002,aab,111,bbb,B,5 3: 003,aac,111,bbc,C,1 4: 004,aad,999,bbd,A,2 こんなデータが入ってるとすると3番目の111の重複しているものは1行のABCの列に1~3のデータを入れたいのです。そして4番目は次の行というふうに。 そのために1に入ってる111を別に格納して2のデータと比較。違ったら次の行へ。同じだったらその行のまま。 intCountには30件のデータが入っています。 アドバイスお願いします。 -------------------------------------- intCount = UBound(Data) Dim p ' ページカウント Dim L ' ラインカウント Dim R ' レコードカウント Dim Point ' 編集用ポイント Dim CodeSave ' Aコード退避用 p = 0 L = 2 R = 0 With objExcelSheet While R <= intCount intRow = (L + p * 40) ' カンマを認識しない strData = split(Data(R),",") CodeSave = strData(3) Do Until(CodeSave <> strData(3)) .Cells(intRow,strData(5)).Value = strData(??)  ←わからない・・・ R = R + 1 If R <= intCount Then strData = split(Data(R), ",") Else Exit Do End If Loop L = L + 1 Wend End With --------------------------------------

  • 二次元配列のVBA

    二次元配列のVBAの書き方がよくわからないのですが、 私が作ったサンプルプログラムのSub 二次元()において 二次元配列で表すにはどうすればいいのでしょうか? Sub 二次元()では 配列を格納する変数はtmpしか使っていませんが もう一つ配列を格納する用の変数を作ればいいのでしょうか? 数字とアルファベットは別々に取り出したいです。 ----------------------------------------------------- Sub 一次元() Dim myStr As String Dim tmp As Variant Dim i As Long For i = 1 To 5 myStr = myStr & "," & i Next myStr = Mid(myStr, 2) tmp = Split(myStr, ",") For i = LBound(tmp) To UBound(tmp) Debug.Print tmp(i) Next i End Sub Sub 二次元() Dim myStr As String Dim tmp As Variant Dim i As Long For i = 1 To 5 myStr = myStr & "," & i & "と" & Chr(64 + i) Next myStr = Mid(myStr, 2) tmp = Split(myStr, ",") For i = LBound(tmp) To UBound(tmp) Debug.Print tmp(i) Next i End Sub

  • 配列の並べ替えのやりかたを教えてください

    適当に 5,1,3,2,4,6 と書かれたテキストがあるとして、 これらの数字を大きい順に並べかえるにはどう 記述すればいいか教えていただけないでしょうか? もともとの並びから任意の数字を参照するところまでは わかりました。よろしくお願いします。 ================================================================ loadLV = new LoadVars(); //LoadVarsオブジェクトを作成 ranking=Array //配列を用意 loadLV.onData = function(data){ ranking = data.split(","); //コンマ区切りでデータを配列 trace("「" + ranking[0] + "」"); //5が出力されます }; loadLV.load("ranking.txt"); //テキストの読み込み

    • ベストアンサー
    • Flash
  • エクセル(VBA)の空白配列の削除について

    エクセルのVBAで配列を使おうと考えています。 データ配列 = Split(データ源, Chr(13)) として、1次元配列に取り込んだところ、chr(10)だけが入力されたデータ配列(?)が出来てしまいました。このデータ配列を詰めたいのですが、何かいい方法が無いでしょうか?教えてください。 元の配列 データ配列(0)  "てすと1" データ配列(1)  chr(10) データ配列(2)  "テスト2" とすれば、 詰めたあと、 データ配列(0)  "てすと1" データ配列(1)  "テスト2" となるようにしたいのです。(配列の最大数が減る必要が必ずしもありません。) for each で回せばいいのでしょうか? Dim 仮 AS Variant for Each 仮 In データ配列    処理をここに書く Next では、上手く行きませんでした。 どなたか?詳しい方がいらっしゃいましたら教えてください。宜しくお願い致します。

専門家に質問してみよう