初めまして。
VB初心者のバロシュといいます。
早速ですが
テキストボックスに入っている文字をカンマ区切りで
スプレッドに表示したいのですが
Dim stArrayDate() As String
stArrayDate = Split(txt_Ins.Text, ",")
ですとstArrayDateにテキスト内のものが格納されて
いないようなのですが、なぜ格納されないのかわかりません。
初歩的な質問かも知れませんが、どうしてもわからないので
教えていただきたく書き込みさせていただきました。
よろしくお願いします。
stArrayDateは配列で取ってるんで
stArrayDate(0)とかstArrayDate(1)とかに入ってるんじゃないですか?
カンマが1つもなければ0にしか入ってないとおもいます。
「スプレッド」ってGrapeCity社の「SPREAD ?.0J」のことでしょうか?
それとも、Microsoft社の「SpreadSheet」の事?
いずれにせよ、VBのバージョンは何なんでしょう?
> stArrayDateにテキスト内のものが格納されていないようなのですが
とのことですが、どうやって確認したんでしょうか?
また、txt_Ins.Textの内容は、具体的にはどういうものだったんでしょう?
あんびさん、回答ありがとうございます。
stArrayDate(i) = Split(txt_Ins.Text, ",")
としてみると型が一致しません、となってしまいます。
ちなみにスプレッドへ書き込むとなった場合は
With spv_Main
.Row = 1
.Col = 1
.Value = stArrayDate(i)
End With
これでよいのでしょうか?
度々申し訳ありませんが、よろしくお願いします。
大吉末吉さん、回答ありがとうございます。
質問内容が不明瞭で申し訳ありませんでした。
「スプレッド」はMicrosoft社の「SpreadSheet」です。
VBは6を使用しています。
stArrayDateにテキスト内のものが格納されていないのは
デバッグで確認しました。
txt_Ins.Textの内容は「aaa,bbbbb,ccc,ddd」になります。
> stArrayDateにテキスト内のものが格納されていないのは
> デバッグで確認しました。
stArrayDate = Split(txt_Ins.Text, ",")
の後ろで、
Debug.Print stArrayDate(0)
Debug.Print stArrayDate(1)
Debug.Print stArrayDate(2)
Debug.Print stArrayDate(3)
を実行してみましたが・・・ちゃんと入ってますけど・・・
> 「スプレッド」はMicrosoft社の「SpreadSheet」です。
Microsoft社の「SpreadSheet」の場合、
Excelと同じなので、
> With spv_Main
> .Row = 1
> .Col = 1
> .Value = stArrayDate(i)
> End With
こういうやり方はできないのでは・・・
#これってGrapeCity社の「SPREAD ?.0J」とかでやる方法ですよね?
例えば、
---------------------------
With spv_Main.Sheets(1)
.Cells(1, 1) = stArrayDate(0)
End With
---------------------------
とか・・・
大吉末吉さん、回答ありがとうございます。
確かにちゃんと格納されていました。失礼しました。
ちなみに
With spv_Main.Sheets
.Cells(1, 1) = stArrayDate(0)
End With
ですと「オブジェクトはこのプロパティ、メソッドをサポート
していません」となってしまいます。
正直「SPREAD ?.0J」などの区別もつかないレベルなので、
申し訳ありませんが、書き込みの仕方も教えていただけると幸いです。
> With spv_Main.Sheets
これって、私の例示した内容と違いますが・・・
具体的には、どの行でエラーになります?
#「With」の行?「.Cells」の行?
> With spv_Main.Sheets
すみません。書き漏れです。
With spv_Main.Sheets(1)でもやってみたのですが、エラー内容は
先ほどの通りで、Withの行でエラーになってしまいます。
あれ変ですね?
「spv_Main」って、「SpreadSheet」コントロールの名前ですよね?
#Excelそっくりで、コントロールの上でマウス右クリックしてでるメニューで
#「バージョン情報」を選択すると、「Office Web COmponets」って出てくるやつ。
コード画面上で、
「Me.spv_Main.」と、書くと候補メニューが出ると思いますが、どういう候補が出ますか?
>Excelそっくりで、コントロールの上でマウス右クリックしてでるメニュー
右クリックしても「バージョン情報」という項目は出てきませんでした。
それとすみませんが、先ほどの「SPREAD ?.0J」というのは
スプリッドのプロパティ→バージョン情報で見れるもののことだった
のでしょうか?
だとしたら申し訳ありません。「SPREAD/OCX V2.5J」となっていました。
失礼いたしました。
ちなみにMe.spv_Main.といれると候補が書ききれないほど出てきたのですが、私判断でそれっぽいものだとColやCol2、RowやRow2などが出てきました。
VB6.0なら、質問とは関係ないのですが
昔デバッグモードでの実行では正しく動くのにexeを作ったら原因不明で
落ちる状況になり色々調べたらMicroSoftのサポートページにwithを使用しているときexeにしたら落ちる事があるという内容の文章にいきついたことがあるので
withはあまり使わないほうがいいですよ。
> SPREAD/OCX V2.5J
あたー。
> 「スプレッド」はMicrosoft社の「SpreadSheet」です。
ではありませんね。
コレはGrapeCity社(当時は「文化オリエント社」)の「SPREAD X.0J」のほうですね・・・
そうでしたら、先ほどのコードは動きません。元の
> > With spv_Main
> > .Row = 1
> > .Col = 1
> > .Value = stArrayDate(i)
> > End With
> #これってGrapeCity社の「SPREAD ?.0J」とかでやる方法ですよね?
こちらの方を使ってください。
#但し「stArrayDate(i)」は「stArrayDate(0)」でしょうけど・・・
大吉末吉さん、誠に申し訳ありませんでした。
With spv_Main
> .Row = 1
> .Col = 1
> .Value = stArrayDate(i)
> End With
でaaaだけは出すことが出来ました。
ご迷惑をお掛けしました。
ご迷惑ついでに1文字ずつ抜き出してカンマがあったらそのあとの
文字は隣のカラムに、といったものを作りたい場合、1文字ずつ
抜き出すのに
stArrayDate = Mid(txt_Ins.Text, 1, 1)
というものを作ったのですが「配列には割り当てられない」と
出てしまいます。なぜaaaは入ったのにこれは入れられないのでしょうか?
重ね重ね申し訳ありませんが、よろしくお願いします。
> stArrayDate = Mid(txt_Ins.Text, 1, 1)
> というものを作ったのですが「配列には割り当てられない」と
> 出てしまいます。なぜaaaは入ったのにこれは入れられないのでしょうか?
これは、
> stArrayDate = Split(txt_Ins.Text, ",")
コレと対比していっているんですよね?
「Split関数」は、文字を分割して「1次元配列」を作る関数です。
ですから、配列である「stArrayDate」に設定できます。
「Mid関数」は、文字列の一部を取り出して「文字列」を作る関数です。
配列を作るわけじゃありませんので、配列である「stArrayDate」には設定できません。
この方法をとるなら、配列要素(文字列)に設定する必要があります。
その際、配列の最大要素数は、貴方が指定してあげなければなりません。
例えば、
---------------------------------------------------------
Dim stArrayDate() As String
Dim position As Long ' どこに設定するかを記録しておく。
position=-1 ' 初期位置は「-1」
ReDim stArrayDate(0) ' とりあえず配列要素を作っておく
・・・・
position=position+1 ’ 設定箇所を+1する
ReDim Preserve stArrayDate(position) ' 配列を大きくする
stArrayDate(position)=Mid(txt_Ins.Text, 1, 1)' 配列の要素に設定
---------------------------------------------------------
とか・・・
>大吉末吉さん、誠に申し訳ありませんでした。
>With spv_Main
> .Row = 1
> .Col = 1
> .Value = stArrayDate(i)
> End With
>でaaaだけは出すことが出来ました。
i=0の時、aaaな訳なんで
>stArrayDate = Mid(txt_Ins.Text, 1, 1)
をしなくても
i=1にしたらbbbが入ってると思います
↑の方で大吉末吉さんが提示してくれている
>Debug.Print stArrayDate(0)
>Debug.Print stArrayDate(1)
>Debug.Print stArrayDate(2)
>Debug.Print stArrayDate(3)
を入れたらイミデイトウインドにaaaやらbbbやらが表示されてませんか?
大吉末吉さん、ありがとうございます。
aがでました。
ではaaaにしたい場合はForなどでループを作ればよいのでしょうか?
そしてカンマが来たら隣のカラムに、といった具合でしょうか?
あんびさん、回答ありがとうございます。
確かにi=1にしたらbbbも入りました。
ですが実は「MID関数を使って1文字1文字カンマかそうでないか判定し
処理する」と指定されていまして・・・
まずはスプレッドへの書き込みの仕方を教えていただこうとして
最初の質問になってしまいました。
回りくどくて申し訳ありませんでした。
> ではaaaにしたい場合はForなどでループを作ればよいのでしょうか?
それで、良いのでは?
#文字列を上書きしないように、注意。(連結しないといけませんね)
> ですが実は「MID関数を使って1文字1文字カンマかそうでないか判定
> し処理する」と指定されていまして・・・
コレが全文(全ての制約?)でしょいか?
「判定」だけ1文字づつやれば、後は何をやってもOK?
だったら、判定は1文字づつで、スプレッドへの設定は、文字列単位というのもありですね。
「aaa,bbbbb,ccc,ddd」で、
先ず、開始位置を「1文字目」とする。
ループしながら「,」を探して「4文字目」を求める。
で、「1文字目から3文字目(「,」の前)までの合計3文字」までをセルに設定。次の開始位置は「5文字目」とする。
5文字目からループを続けて、次の「,」を探して「10文字目」を求める。
で、「5文字目から9文字目(「,」の前)までの合計5文字」までをセルに設定。次の開始位置は「11文字目」とする。
・・・
とか。
制約は
テキストボックスの文字列をカンマ区切りでスプレッドの1行目の各項目へ表示させる。
テキストボックスの文字列をカンマ区切りで一旦1次元配列に読み込み、1次元配列からスプリッドへの表示にはRowプロパティー、Colプロパティー、Textプロパティーを使用する。
文字列をカンマ区切りで切り出すには、For文を使用し文字列の1文字1文字をカンマかそうでないか判断し処理すること。その際、1文字の切り出しにはMid関数を使用すること。
になります。
「1文字目から3文字目(「,」の前)までの合計3文字」をセルに設定、
ということはそういった関数があるのでしょうか?
> 「1文字目から3文字目(「,」の前)までの合計3文字」をセルに設定、
> ということはそういった関数があるのでしょうか?
単に、「Mid関数でまとめて3文字処理すれば・・・」と思ったんですが・・・
良く考えてみると、それほど良くはなりませんね。
#とりあえず、忘れてください。
なるほど、
> テキストボックスの文字列をカンマ区切りで一旦1次元配列に読み込み、
> 1次元配列からスプリッドへの表示にはRowプロパティー、Colプロパティー、Textプロパティーを使用する。
おや?「Textプロパティ」ですか。
#先ほどの、コードでは「Valueプロパティ」でしたが、間違いってことですね。
> 文字列をカンマ区切りで切り出すには、
> For文を使用し文字列の1文字1文字をカンマかそうでないか判断し処理すること。
> その際、1文字の切り出しにはMid関数を使用すること。
ふむ。特に問題になりそうな制約は無いですね。
#ただ、処理的にはちょっと回りくどい感じですね・・・
#思いつく限りのややこしい方法を指定した感じ?
今まででた情報で何とかなりそうですね。
<1次元配列への設定>
・配列要素を準備する。
・Forで文字数分ループする。
・Mid関数で、1文字調べる。「,」じゃ無いなら、配列要素へ連結
・「,」なら、次の配列要素を対象にする(要素数を増やす)
・文字がなくなるまで繰り返す。
<スプレッドへの設定>
・設定対象セルを1行目の左端(Row=1、Col=1)にする。
・Forで配列要素数分ループする
・Col/Row/Textを使ってセルに設定する。
・設定対象セルを右隣にし、配列要素が無くなるまで
という感じ?
とりあえず
For position = -1 To Len(txt_Ins.Text)
position = position + 1 ' 設定箇所を+1する
ReDim Preserve stArrayDate(position) ' 配列を大きくする
stArrayDate(position) =
stArrayDate(position) + Mid(txt_Ins.Text, 1, 1) ' 配列の要素に設定
Next
というのを作ってみたのですがstArrayDate(position)には
aしか格納されません。なんとなく勘違いして解釈しているというのは
わかるので、指摘していただけると幸いです。
> なんとなく勘違いして解釈しているというのは
> わかるので、指摘していただけると幸いです。
では指摘を。
> Mid(txt_Ins.Text, 1, 1)
引数の指定を間違ってますね。
ヘルプで「Mid関数」を調べてください。
#ヘルプが無いなら、ネットでも可。
以下は、VBScript用のヘルプですが、機能的にはVB6とほぼ同じなので載せておきます・・・
(http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/script56/html/vsfctMid.asp)
それから、
> position
の使い道もちょとおかしいです。
「チェックする文字の場所」と「設定を行う要素の位置」を同じ変数では扱えません。
別々の変数を使ってください。
すみません。自分で考えてみたのですが、MIDは読み込む文字列の指定が
おかしいということでしょうか?
それと「チェックする文字の場所」= 何文字目か、
としたら「設定を行う要素の位置」 = 表示する文字列
という認識でよろしいでしょうか?
> MIDは読み込む文字列の指定がおかしいということでしょうか?
Mid関数の第2引数には、「何文字目(から)取り出すか」を指定します。
> Mid(txt_Ins.Text, 1, 1)
「1」って書いてしまうと、先頭の1文字目以外取り出せません。
> と「チェックする文字の場所」= 何文字目か、
> としたら「設定を行う要素の位置」 = 表示する文字列
それであってます。多分・・・
「表示する文字列」=「配列に設定する文字列」≒「設定を行っておく要素番号」ですから・・・
「aaa,bbbbb,ccc,ddd」で、
『4文字目は「,」』と言う時の「4」が「チェックする文字の場所」
stArrayDate(0)に"aaa"を設定して、
stArrayDate(1)に"bbbbb"を設定して、
と言う場合の「0」や「1」が「設定を行う要素の位置」
です。
とりあえず、インデントする癖をつけてください。
>For position = -1 To Len(txt_Ins.Text)
>position = position + 1 ' 設定箇所を+1する
>ReDim Preserve stArrayDate(position) ' 配列を大きくする
>stArrayDate(position) =
>stArrayDate(position) + Mid(txt_Ins.Text, 1, 1) ' 配列の要素に設定
>Next
前回カンマ位置を退避する変数を準備する
文字の長さまでループする
カンマかどうかの判定をする 以下カンマの場合
stArrayDateの領域を確保する
前回カンマ位置からカンマの位置の前の文字をstArrayDateに入れる
前回カンマ位置を現在カンマ位置とする
全文字判定が終わったらstArrayDateで確保した領域分ループ
spreadに入れる
ですね。
あと、カンマが無かったときの処理や文字入力が0文字だった時
1文字目がカンマだった時、最後の文字がカンマだったとき
などをテストしてください。
度々申し訳ありません。
とりあえず全て読み込むものを作ろうと
i = 1
j = 0
For position = -1 To Len(txt_Ins.Text)
position = position + 1 ' 設定箇所を+1する
ReDim Preserve stArrayDate(position) ' 配列を大きくする
stArrayDate(j) = Mid(txt_Ins.Text, i, 1) ' 配列の要素に設定
i = i + 1
j = j + 1
Next
を作ってみたのですが、上手くいきません。
これだとカンマ区切りは別にして全て表示されると思ったのですが、
なぜaしか表示されないのでしょうか?
あんびさん、すみません。
ページを開きっぱなしにしていたので更新されていたのが
分かりませんでした。
正直もうどうすればいいのかわかりません。
こんなことを言ったら怒られるというのはわかっているのですが、
回答例のようなものを見せていただくことは出来ないでしょうか?
身勝手ではありますが、よろしくお願いします。
> 正直もうどうすればいいのかわかりません。
では、諦めて「Split関数」を使った方法を採用してはどうです?
こちらなら、分かるんですよね?
> 回答例のようなもの
って・・・どういうものの事を言っているんでしょう?
「実際に動作するコード」を提示しろってことでしょうか?
#そもそも「『回答』例」って・・・
で、それを見てどうするつもりですか?
「そのコードを理解して、もっと良いプログラムに作る変える」?
コレまでのやり取りを見る限り、できるとは思えませんけど・・・
「そのコードを、そのまま使う」と言う事になるのでは?
#つまり実施「代わりに作ってくれ」と同じ意味になりそう・・・
ってことで、
「もう少し、頑張ってみる」と言うことでしたら、アドバイスを続けますが、
「諦める」ってことなら、コレで失礼されて頂たいいんですが・・・
失礼しました。
もう少し頑張ってみますので、よろしくお願いします。
では、
-------------------------------------------------------------
i = 1
j = 0
For position = -1 To Len(txt_Ins.Text)
position = position + 1 ' 設定箇所を+1する
ReDim Preserve stArrayDate(position) ' 配列を大きくする
stArrayDate(j) = Mid(txt_Ins.Text, i, 1) ' 配列の要素に設定
i = i + 1
j = j + 1
Next
-------------------------------------------------------------
コレをベースに考えましょう。
(1)変数「j」
変数「j」って何の為に使っているんでしょう?
無意味にカウントアップしているだけに見えますけど・・・
#コレが、配列の要素数(配列の大きさや、設定位置を示す変数)になるのかな・・・
だとすると、(2)で書いているように、無条件のカウントアップは駄目ですね。
#それから、配列は一度、「ReDim stArrayDate(0)」とかで、初期化しておいたほうが良いです。
(2)変数「position」
> For position = -1 To Len(txt_Ins.Text)
ココで、「position」はループカウンタに使われています。
つまり、自動的に加算されますので、
> position = position + 1 ' 設定箇所を+1する
は不要です。
さらに、ここでは、「文字数分ループ」しなけれなりません。
上記だと、-1,0,....と、「文字数+2」回ループしてしまいます。
「1」からはじめれば十分です。
また、無条件で
> ReDim Preserve stArrayDate(position) ' 配列を大きくする
こうやってますが、配列を大きくしなくてはならないのは","を見つけた時だけのはずです。
逆に、配列に設定するのは、","じゃ無いときだけです。
「If 〜 Then 〜 Else 」を使用して、条件わけを行ってください。
(3)文字列の連結
> stArrayDate(j) = Mid(txt_Ins.Text, i, 1) ' 配列の要素に設定
こうやっていますが、コレでは単なる代入(上書き)です。
stArrayDate(j)に"a"が入っている状態で、後ろにもう一つ文字を追加する様な場合、
> stArrayDate(j) = stArrayDate(j) & Mid(txt_Ins.Text, i, 1) ' 配列の要素に設定
の様な記述をする必要があります。
他にも、色々指摘事項はありますが・・・とりあえず、大問題を3点
頑張ってください。
本当に申し訳ありませんでした。
正直アドバイスを活かしきれていないのですが、
自分でやってみたのでアドバイスをお願いします。
i = 1
j = 0
k = 1
For position = -1 To Len(txt_Ins.Text)
position = position + 1
ReDim Preserve stArrayDate(position)
If Mid(txt_Ins.Text, i, 1) <> "," Then
stArrayDate(j) = stArrayDate(j) + Mid(txt_Ins.Text, i, 1)
ElseIf Mid(txt_Ins.Text, i, 1) = "," Then
k = k + 1
End If
With spv_Main
.Row = 1
.Col = k
.Text = stArrayDate(j)
End With
i = i + 1
j = j + 1
Next
これですとa,bが一文字しか表示されません。
一文字しか表示されないのは+では連結できないということだと
想像できました。
しかしデバッグをしてみると、bの後ろの,を読み込んだところで
処理が終わってしまいます。
To Len(txt_Ins.Text)はちゃんと17になっているのですが
なぜ途中でループを抜けてしまうのでしょうか?
失礼しました。
書き込みが入れ違いになってしまいました。
もう一度考えてみます。
改めて作ってみました。
i = 1
k = 1
For position = 1 To Len(txt_Ins.Text)
ReDim stArrayDate(position)
If Mid(txt_Ins.Text, i, 1) <> "," Then
stArrayDate(position) = stArrayDate(position) & Mid(txt_Ins.Text, i, 1)
With spv_Main
.Row = 1
.Col = k
.Text = stArrayDate(position)
End With
ElseIf Mid(txt_Ins.Text, i, 1) = "," Then
k = k + 1
ReDim Preserve stArrayDate(position)
End If
i = i + 1
Next
これですとa〜dまで出るようになったのですが、やはり
一文字しか表示されません。なぜ上書きされてしまうのでしょうか?
ちょっと、根本的な確認です。
私は、制限事項の
> テキストボックスの文字列をカンマ区切りで一旦1次元配列に読み込み、
は、
stArrayDate(0)に"aaa"、stArrayDate(1)に"bbbbb"・・・
と、読み込むと解釈したんですが、あってますよね?
その前提として、
> ReDim stArrayDate(position)
は、ループの外(Forの行より前)で1回だけやればよいです。
#例えば「k=1]と「For〜」の間で「ReDim stArrayDate(1)」とか・・・
ループの中で毎回初期化してしまうと、それまでの苦労が台無しです。
それから、
> stArrayDate(position)
としてますが、変数「position」は「文字列のチェック位置」ですよね?
ちょっと前(2007/02/08(木) 22:00:34)にも書きましたが、
「設定を行う要素の位置」と、区別してください。
#多分「stArrayDate(position)」の記述は「stArrayDate(k)」の間違いですよね。
おお、かなり進歩してきましたね
For position = 1 To Len(txt_Ins.Text)
でループさせるのなら、
ReDim stArrayDate(position)
で毎回配列を取り直すと、1文字分しか入らない領域になりますよね?
-----------------------------------------------------------
For position = 1 To Len(txt_Ins.Text)
^^^^^^^^
これはiとしましょう
で、i=1も不要でi=i+1も不要です
NEXTに来たら、自動で+1されます
If Mid(txt_Ins.Text, i, 1) <> "," Then
もiで判定しているので、それだけでかなり良くなりますがもう少しでしょうね
最初にでてくるReDim stArrayDate(position)は当然不要です
大吉末吉さん、あんびさん、ありがとうございます。
どうにかこんな感じで完成させることが出来ました。
k = 1
ReDim stArrayDate(k)
For i = 1 To Len(txt_Ins.Text)
If Mid(txt_Ins.Text, i, 1) <> "," Then
stArrayDate(k) = stArrayDate(k) & Mid(txt_Ins.Text, i, 1)
With spv_Main
.Row = 1
.Col = k
.Text = stArrayDate(k)
End With
ElseIf Mid(txt_Ins.Text, i, 1) = "," Then
k = k + 1
ReDim Preserve stArrayDate(k)
End If
Next
基本知識の足りなさや、アドバイスをちゃんと理解していなかったり、
失言までしてしまい、イラッとさせてしまったこともあったと思うのですが、
根気よくお付き合い下さいましてありがとうございました。
また質問させていただくこともあると思うのですが、もしよろしければ
またご教授よろしくお願いします。
本当にありがとうございました。
| ツイート |
|