C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: Split関数の空データの判別って?


(過去ログ 131 を表示中)

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■77733 / inTopicNo.1)  Split関数の空データの判別って?
  
□投稿者/ たろう (1回)-(2015/11/19(Thu) 16:09:04)

分類:[Microsoft Office 全般] 

Access2013のVBAでSplit関数を使ってExcelからデータをコピーしてデータをテーブルに保存しています。

Excelの表で50個の列データを複数行コピーして、行ごとにvbCrlfで分割し、行のデータをvbTab区切りでSplit関数で分割します。
最後の行データが全て埋まっている時はデータのカウントが50になるのですが、
最後の行データが先頭から40個しか埋まっていないとカウントが50になりません。
省略されているのか?勝手にTrimかけられているのか?
空のデータがあってもタブコードは認識してるはずですよね?

Split関数のパラメータを変えても、テキストボックスをリッチテキストに変えても50個認識されません。

空のデータも認識させる方法はありますか?

引用返信 編集キー/
■77734 / inTopicNo.2)  Re[1]: Split関数の空データの判別って?
□投稿者/ たろう (2回)-(2015/11/19(Thu) 16:12:10)
説明が少し抜けていました。
カウントの取得にはUBoundを使っています。

ary_value = Split(v_line, vbTab)
cnt = UBound(ary_value)

ソースはこんな感じです。

引用返信 編集キー/
■77737 / inTopicNo.3)  Re[1]: Split関数の空データの判別って?
□投稿者/ 魔界の仮面弁士 (565回)-(2015/11/19(Thu) 16:32:09)
No77733 (たろう さん) に返信
> Access2013のVBAでSplit関数を使ってExcelからデータをコピーしてデータをテーブルに保存しています。
Access VBA で Split を使う場合には、比較モードオプションを明示指定した方が安全です。
 vbBinaryCompare
 vbTextComapare
 vbDatabaseCompare

試しに、バイナリ比較モードで Split してみるとどうなりますか?



> Excelの表で50個の列データを複数行コピーして、行ごとにvbCrlfで分割し、
> 行のデータをvbTab区切りでSplit関数で分割します。
改行入りのデータ(Excel 上では Lf 改行)は含まれていますか?


> 最後の行データが全て埋まっている時はデータのカウントが50になるのですが、
「最後の行データが全て埋まっている」というのは、Excel でいうところの
  lastRow = Sheet1.UsedRange.Row + Sheet1.UsedRange.Rows.Count - 1
  Set rng = Sheet1.Rows(lastRow).Columns("A:AX")
  ' rng.Select
で示される 50 個のセル全てに、何かしらのデータが入っている状態、という意味でしょうか?


> 最後の行データが先頭から40個しか埋まっていないとカウントが50になりません。
・『列データを複数行コピー』というのは、どういう操作を意味していますか?

・Split に渡した文字列の内容は、具体的にはどうなっていますか?
 たとえば下記のようにすれば、文字列データの内容を正確に把握できます。

 Debug.Print "Length="; Len(copiedString)
 For i = 1 To Len(copiedString)
  Debug.Print Right("0000" & Hex(AscW(Mid(copiedString, i, 1))), 4) & " ";
 Next
 Debug.Print


> 省略されているのか?勝手にTrimかけられているのか?
それを判断できるのは、実際の環境に触れているたろうさんだけです。

少なくとも、コピーした時点で削られてしまっているのか、それとも、
コピーした時点では削られていないのに、Split した時点で削られているかは
ご自身で調査できますよね。


> Split関数のパラメータを変えても、テキストボックスをリッチテキストに変えても50個認識されません。
分割後の個々の要素を元データと比較してみた場合、どのような違いがありますか?
引用返信 編集キー/
■77738 / inTopicNo.4)  Re[2]: Split関数の空データの判別って?
□投稿者/ たろう (3回)-(2015/11/19(Thu) 16:54:38)
ありがとうございます。

> 試しに、バイナリ比較モードで Split してみるとどうなりますか?

こちらも全て試してみましたが変わりませんでした。

> 改行入りのデータ(Excel 上では Lf 改行)は含まれていますか?

テキストエディタに貼り付けるとCrLfになっていました。
さくらエディタですと、\r\n の状態です。
Accessのテキストボックスに貼りつけた場合も、vbCrlfでSplitできていて、最後の行データが50個埋まっている場合には成功しますので。


> で示される 50 個のセル全てに、何かしらのデータが入っている状態、という意味でしょうか?

この状態です。


> ・『列データを複数行コピー』というのは、どういう操作を意味していますか?

50個の列データを10行コピーする場合、A1からAX10までを選択しコピーしています。


>>省略されているのか?勝手にTrimかけられているのか?
> それを判断できるのは、実際の環境に触れているたろうさんだけです。

自分でTrimをかけてはいないので、この関数が空のデータがTab区切りである時どう認識しているのかがわかりません。


>>Split関数のパラメータを変えても、テキストボックスをリッチテキストに変えても50個認識されません。
> 分割後の個々の要素を元データと比較してみた場合、どのような違いがありますか?

認識されているデータは例えば50個のセルに先頭から35個目までデータが入っていると、途中に空のデータが入っていても35個目のデータまでは認識されます。
カウントは35とされます。
引用返信 編集キー/
■77739 / inTopicNo.5)  Re[2]: Split関数の空データの判別って?
□投稿者/ たろう (4回)-(2015/11/19(Thu) 17:28:10)
大変申し訳ありません。

テキストボックスにデータを貼りつけた時点ではTabデータはあるのですが、コマンドボタンをクリックした瞬間?
「ボタン_クリック」プロシージャに飛んだ時にテキストボックスの
.Value
.Text
の段階で既にTrimがかかっているようでした。

Trimがかからない設定というか、プロパティの変更で行えるのでしょうか?
プロパティ設定が原因の場合、どのプロパティを変更すれば良いでしょうか?

引用返信 編集キー/
■77740 / inTopicNo.6)  Re[2]: Split関数の空データの判別って?
□投稿者/ サーモン (1回)-(2015/11/19(Thu) 17:31:09)
2015/11/19(Thu) 17:33:15 編集(投稿者)

例えば、サクラエディタに貼り付けを行うと選択セル分忠実にタブを貼り付けますが、
メモ帳に貼り付けた場合には、1個以上のタブで終わる場合にはタブが削除されるようです。
これはそういう仕様と考えるしかないかも知れません。

IEのtextareaに後ろがタブのものを貼り付けた場合でも、同様に後ろのタブは削除されますね。

引用返信 編集キー/
■77741 / inTopicNo.7)  Re[3]: Split関数の空データの判別って?
□投稿者/ たろう (5回)-(2015/11/19(Thu) 17:37:29)
ありがとうございます。

変数に格納する前に
.Value
.Text
のデータをイミディエイトウィンドウで確認すると既にTrimがかかったデータになっていました。

テキストボックスをリッチテキストに変更しても変わらないのですが、やはり仕様なんですか。

Excelからデータをコピーする時に最後の行にダミーデータでも入れるしか無いのでしょうか?

引用返信 編集キー/
■77743 / inTopicNo.8)  Re[3]: Split関数の空データの判別って?
□投稿者/ 魔界の仮面弁士 (566回)-(2015/11/19(Thu) 18:13:51)
No77738 (たろう さん) に返信
> 例えば50個のセルに先頭から35個目までデータが入っていると、
> 途中に空のデータが入っていても35個目のデータまでは認識されます。
> カウントは35とされます。
その時、ペーストされた文字列に タブは何個含まれていましたか?

Dim strLine As String
Dim ary() As String

Debug.Print "** 50列すべてにデータが入っている場合 **"

strLine = ""
strLine = strLine & "01|02|03|04|05|06|07|08|09|10|"
strLine = strLine & "11|12|13|14|15|16|17|18|19|20|"
strLine = strLine & "21|22|23|24|25|26|27|28|29|30|"
strLine = strLine & "31|32|33|34|35|36|37|38|39|40|"
strLine = strLine & "41|42|43|44|45|46|47|48|49|50"
strLine = Replace(strLine, "|", vbTab, 1, -1, vbBinaryCompare)

ary = Split(strLine, vbTab, -1, vbBinaryCompare)
Debug.Print UBound(ary) - LBound(ary) + 1


Debug.Print "** 50列中、35列目までしかデータが無かった場合 **"

strLine = ""
strLine = strLine & "01|02|03|04|05|06|07|08|09|10|"
strLine = strLine & "11|12|13|14|15|16|17|18|19|20|"
strLine = strLine & "21|22|23|24|25|26|27|28|29|30|"
strLine = strLine & "31|32|33|34|35||||||"
strLine = strLine & "|||||||||"
strLine = Replace(strLine, "|", vbTab, 1, -1, vbBinaryCompare)

ary = Split(strLine, vbTab, -1, vbBinaryCompare)
Debug.Print UBound(ary) - LBound(ary) + 1



> この関数が空のデータがTab区切りである時どう認識しているのかがわかりません。
そういうことでは無く、原因の特定のために、再現性を確立させましょう、という話です。

たとえば:
 strLine = タブ区切り文字列データ
 ary = Split(strLine, vbTab, -1, vbBinaryCompare)
とした場合、strLine の内容がどういう文字列の場合に、
分割後の ary がどうなっているのか、関係性を調査しましょう、ということです。


そのためにも、実際に「50 個に分割されなかった時」に Split に渡していた文字列を、
前回の回答に書いた AscW で一文字ずつ精査してみてください。

現状は、実際の環境に触れているたろうさんしか調査できませんが、
具体的なデータが提供されれば、たろうさん以外の第三者でも検証できます。


その結果、予想と違う結果になるようであれば、Split の問題が疑われますし、
Split の動作に問題が無さそうなら、ペーストされたタブ区切り文字列データと、
Excel からコピーされてきた内容の差異ということになりますよね。



> 最後の行データが50個埋まっている場合には成功しますので。
了解です。


> テキストエディタに貼り付けるとCrLfになっていました。
> さくらエディタですと、\r\n の状態です。

今回のように、原因箇所を特定するためのケースでは、
クリップボードの内容をバイナリとして表示できるタイプの
クリップボードビューワーで確認されることをお奨めします。
(今回、そこまでの調査が必要になるかどうかは別として)


何故バイナリ形式での取得をすすめるかと言うと、
クリップボードは通常、複数の形式でデータを保持しており
(Unicodeテキスト、テキスト、OEMテキスト、リッチテキストなど)、
その中のどれがペーストされるかは、アプリケーションによって異なるためです。

また、アプリケーションによってはペースト時に改行や文字コードを
変換してしまうものもありますので(Visual Studio .NET など)、
正確な情報を知ろうとする場合には、バイナリレベルで調査できる
ツールの方が、問題箇所を特定しやすくなります。



>>・『列データを複数行コピー』というのは、どういう操作を意味していますか?
> 50個の列データを10行コピーする場合、A1からAX10までを選択しコピーしています。
コピーしたデータは、どのように取り出していますか?

・ユーザーが TextBox に貼り付け、その Value を読み取る
・VBA から acCmdPaste を通じて貼り付け、その Value を読み取る
・CF_TEXT を直接取り出す
 https://msdn.microsoft.com/ja-jp/library/office/ff194373.aspx
引用返信 編集キー/
■77744 / inTopicNo.9)  Re[4]: Split関数の空データの判別って?
□投稿者/ 魔界の仮面弁士 (567回)-(2015/11/19(Thu) 19:30:12)
あう。文章書いている間に話が進んでいたようで。

No77741 (たろう さん) に返信
> テキストボックスをリッチテキストに変更しても変わらないのですが、やはり仕様なんですか。

Forms 2.0 は使えないでしょうか?

手元の環境(Access 2013 / 64bit)では、
Access.TextBox 型のテキストボックスの代わりに、
MSForms.TextBox 型のテキストボックスを使ってみたところ、
末尾タブも含めてペーストされました。

RichTextBox は試していません。(64bit 環境のせいか、そもそも選択できない)


なお、ユーザー操作ではなく、コントロールの Value プロパティに
文字列を直接送り込んだ場合は、タブが削られることは無いようです。
引用返信 編集キー/
■77750 / inTopicNo.10)  Re[5]: Split関数の空データの判別って?
□投稿者/ たろう (6回)-(2015/11/20(Fri) 13:40:35)
> Forms 2.0 は使えないでしょうか?

ありがとうございます!
使いえました!
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -