[[20140920112501]] 『マルチレコードについて』(フェンダー) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『マルチレコードについて』(フェンダー)

いつもお世話になります。
下記のようなVBA テキスト入出力をしたいのですが、
参考になるサイトを、ご存知の方いないでしょうか?

区切りのない5byte固定レコード。
出力前9レコードで45byte
10AAA
20BBB
20CCC
10DDD
20EEE
20FFF
20GGG
10HHH
20III

出力後6レコードで合計60byte
10AAA20BBB
10AAA20CCC
10DDD20EEE
10DDD20FFF
10DDD20GGG
10HHH20III

1レコードから順番に
10が先頭の起点になり、
20のレコードが10の後列に必ずきます。
なにから始めればよいか、現在はまだ
思考中です。
どなたかアドバイスお待ちしております。

< 使用 Excel:Excel2010、使用 OS:Windows7 >


 とりあえずの ToyProgram ですが。

 Sub sample()
    Const dataPath = "sample.dat"

    MakeData dataPath
    MsgBox ReadData(dataPath)
 End Sub

 Sub MakeData(dataPath)
    Dim fso As New Scripting.FileSystemObject
    fso.CreateTextFile(dataPath).Write "10AAA20BBB20CCC10DDD20EEE20FFF20GGG10HHH20III"
 End Sub

 Function ReadData(dataPath)
    Dim fso As New Scripting.FileSystemObject
    Dim dat As String
    Dim dat10 As String
    Dim res

    Dim data As Scripting.TextStream
    Set data = fso.OpenTextFile(dataPath)
    Do While data.AtEndOfStream = False
        dat = data.Read(5)
        Select Case Left(dat, 2)
        Case "10": dat10 = dat
        Case "20":
            res = res & IIf(res = "", "", vbNewLine)
            res = res & dat10 & dat
        Case Else
        End Select
    Loop
    data.Close
    ReadData = res
 End Function
(Mook) 2014/09/20(土) 12:27

サンプルデータ
どうもありがとうございます。
参考になります。
因みに、sample.datデータを作成すれば
動作するようになるのでしょうか?
(フェンダー) 2014/09/20(土) 23:30

 見るべきはそこではないと思っていたのですがw。
 固定バイト単位で処理する例のつもりで書きました。

 データの形式の説明がなかったので、とりあえずファイルにしましたが
 パケットでもDB でもなんでもかまわないと思います。

 >なにから始めればよいか、現在はまだ思考中です。 
 の取っ掛り程度の参考にしてください。
(Mook) 2014/09/20(土) 23:44

そうでしたか。
コードの方を参考にさせていただきます。
また何かありましたら
ご相談させてください。
どうもありがとうございました。
(フェンダー) 2014/09/20(土) 23:55

 読み返したら、テキストって書いてありましたね。
 45バイトとあったので改行コードがないと思ったのですが、
 1行1レコードであれば 

 data.Read(5)
 を
 data.ReadLine()
 とすれば、良いかと思います。

 あと、TextStream は 通常のTextFile でよいですね。
(Mook) 2014/09/21(日) 00:06

 入出力前に用意するデータをどのように渡すか考えたのですが
 カンマ区切りのCSVで対応することにしました。(改行あり)
 区切りがないテキストデータでも改行なしでも
 その用途に合わせて用意できるのですが・・・

 サンプルコードを見させていただいたのですが
 考え方として
 エクセル表で考えた場合
 レコードのAセルに"10"がある場合
 次のレコードのAセルに"20"が続くまでは
 Aセルの"10"があるレコードを増やし
 Aセルの"20"があるレコードと合わせる。
 といった考え方でプログラムを考えればよろしいでしょうか?

 なにか考え方のアドバイスをいただけると助かります。

(fennda- ) 2014/09/24(水) 22:08


すいません。
せっかく作成して頂いたので
動きだけでもみたいのですが

 fso As New Scripting.FileSystemObjecの部分が
ユーザー定義型は定義されていませんとなります。

これだけでもアドバイス頂けないでしょうか。
どうぞよろしくお願いします。

(フェンダー) 2014/09/25(木) 16:16


参考に下記URLをだします
http://blog.livedoor.jp/excelvbamemo/archives/53397448.html
わからないときはそのまま検索すると答えが出ます。今回の場合だと

Scripting.FileSystemObject ユーザー定義型は定義されていません

とgoogleなどで検索すれば答えのヒントが出てきます。
わからないときは検索してみるとこの疑問ならすぐに解決できます。

ちなみに上のfennda-さんとフェンダーさんは同じでよろしいですか。
(デイト) 2014/09/25(木) 16:39


すいません。
半角で記載して気が付きませんでした。
fennda-はフェンダーと同じになります。
ご質問前に検索したのですが、よく見てませんでした。
解決しましたので、参考にさせていただければと思います。
(フェンダー) 2014/09/25(木) 19:42

提示いただいたコードは
fso.CreateTextFile(dataPath).Writeに
よって
"10AAA20BBB20CCC10DDD20EEE20FFF20GGG10HHH20III"の文字列に対して
書き出していると思いますが

こちらで宣言した
dim レコード(1 To 5) As Byteに

fso.CreateTextFile(dataPath).Write "10AAA20BBB20CCC10DDD20EEE20FFF20GGG10HHH20III"の
"10AAA20BBB20CCC10DDD20EEE20FFF20GGG10HHH20III"の部分に

値を渡して、検証したいのですが
ご教授願いませんでしょうか。
宜しくお願いします。

(フェンダー) 2014/09/30(火) 10:00


 Byte は 0-255 の「数値」を扱うデータ型ですから、文字ではなく ASCII コード等になる
 と思いますが、そのあたりの仕様を明示してはどうでしょうか。

 文字列から文字コードに変換するのは CODE 関数です。
http://www.becoolusers.com/excel/code.html

 文字列を一括で1文字ずつ配列に入れることは出来ませんので、MID などで切り出しながら
 個別に配列に代入する処理になると思います。

(Mook) 2014/10/01(水) 11:25


アドバイスどうもありがとうございます。

1レコードごとに含まれる情報は
1byte文字 ASCII
2byte文字 SHIFTJISになります。

Mook様から提示して頂いた
サンプルコードを参考に
よく使用する下記の
コードに
引数として渡すプログラムが出来ればと思っております。
まだ検証中ですが・・・

検証中のコードをそのまま記載します。

Sub Main()

コードは削除しました。

End Function

データは改行付のファイルを作成し
セルにファイル場所を指定し

10AAA
20BBB
20CCC
10DDD
20EEE
20FFF
20GGG
10HHH
20III
5byteごとに入出力してます。

(フェンダー) 2014/10/01(水) 13:55


 仕様を読み解く気力と時間が無いので回答では無いですが
Mookさんの以下の部分について
 > 文字列を一括で1文字ずつ配列に入れることは出来ませんので、MID などで切り出しながら
 > 個別に配列に代入する処理になると思います。
 
こんな書き方も出来るよって事でサンプルコードだけ
 
Sub test()
    Dim byt() As Byte
    byt = "123456"
    MsgBox byt
    byt = StrConv("123456", vbFromUnicode)
    MsgBox byt
End Sub
(ご近所PG) 2014/10/01(水) 15:31

 なるほど。
 フェンダーさんの例には適用できないですけれど、ASCII 文字列のByteへの格納は
    byt = StrConv("123456", vbFromUnicode)
 で出来そうですね。

 参考になりました。
(Mook) 2014/10/01(水) 16:21

 私も
 >こんな書き方も出来るよって事でサンプルコードだけ

 という箇所だけですが、 APIのMoveMemoryを使った例です。

 Option Explicit
 Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
    (ByRef Dest As Any, ByVal Source As String, ByVal Length As Long)
 Sub test()
    Dim g0 As Long
    Dim S(1 To 5) As Byte
    Dim mystr As String
    mystr = "1234567890"
    MoveMemory S(1), Mid(mystr, 1, 5), UBound(S)
    For g0 = LBound(S) To UBound(S)
       Debug.Print Hex(S(g0))
    Next
    Debug.Print "一回目"
    MoveMemory S(1), Mid(mystr, 6, 5), UBound(S)
    For g0 = LBound(S) To UBound(S)
       Debug.Print Hex(S(g0))
    Next
    Debug.Print "二回目"
 End Sub

 尚、64Bit版の場合、APIの宣言部の訂正が必要です。

http://www.saka-en.com/office/vba-declare-statement-update-excel-2013/

(ichinose) 2014/10/02(木) 06:49


 この手の文字列をバイナリ処理はたいてい C/C++ を使ってしまいますが、VBA でもいろいろ
 出来るものですね。

 FSO や Stream でも Write、Read 系はバイナリでの処理が出来そうですが、ここも苦手な
 ところです。

 いろいろと参考になりました。

(Mook) 2014/10/02(木) 11:27


サンプルデータどうもありがとうございます。
見慣れない処理方法ですので勉強に、なります。
とりあえず、生データから、
扱うという前提でバイナリ処理から、検証しようとしたのですがなかなか難しいです。
テキストデータにしてから、処理するという方法も
あるのですが。
言語はともかく、処理方法だけでも勉強できればと
思ったのですが時間がかかりそうです。
(フェンダー) 2014/10/02(木) 17:54

お世話になります。
バイナリ処理で考えていたのですが
CSVデータによる
データベースへの取り込みによるデータ編集に変更しました。

Sub main()

Dim db As DAO.Database
Dim rs(1) As DAO.Recordset
Dim FSO As FileSystemObject
Dim mainStream As TextStream
Dim myData As Variant
Dim 事務所 As String, i As Integer

Set db = CurrentDb

Set rs(1) = db.OpenRecordset("テーブル", dbOpenDynaset) 'テーブルファイルをセット

Set FSO = CreateObject("Scripting.FileSystemObject")
Set mainStream = FSO.OpenTextFile("C:\testout.txt", ForReading)

Do Until mainStream.AtEndOfStream
myData = Split(mainStream.ReadLine, ",")
Select Case myData(0)
Case "10"
事務所 = myData(0) & "," & myData(1) & "," & myData(2) & "," & myData(3)

For i = 1 To 4

Next

Case Else
rs(1).AddNew
rs(1).Fields(0) = 事務所
For i = 1 To 4
rs(1).Fields(i) = myData(i)
Next
rs(1).Update
End Select
Loop
mainStream.Close

End Sub

現在、上記のコードで

10,事務所1,1,2
20,Aさん,4,5,6
20,Bさん,7,8,9
20,Cさん,10,11,12
10,事務所2,13,14
20,Dさん,16,17,18
20,Eさん,19,20,21
20,Fさん,22,23,24
20,Gさん,25,26,27

のようなテストデータを

10,事務所1,1,2,20,Aさん,4,5,6
10,事務所1,1,2,20,Bさん,7,8,9
10,事務所1,1,2,20,Cさん,10,11,12
10,事務所2,13,14,20,Dさん,16,17,18
10,事務所2,13,14,20,Eさん,19,20,21
10,事務所2,13,14,20,Fさん,22,23,24
10,事務所2,13,14,20,Gさん,25,26,27

のようにデータ編集したいのですが

※イメージは

10AAA
20BBB
20CCC
10DDD
20EEE
20FFF
20GGG
10HHH
20III

から

10AAA20BBB
10AAA20CCC
10DDD20EEE
10DDD20FFF
10DDD20GGG
10HHH20III

と同じです。

事務所レコードのエリアを
20のレコードエリアに結合する際に

事務所 = myData(0) & "," & myData(1) & "," & myData(2) & "," & myData(3) ですと

同じフィールドに

"10,事務所1,1,2",20,Aさん,4,5,6
"10,事務所1,1,2",20,Bさん,7,8,9
"10,事務所1,1,2",20,Cさん,10,11,12
"10,事務所2,13,14",20,Dさん,16,17,18
"10,事務所2,13,14",20,Eさん,19,20,21
"10,事務所2,13,14",20,Fさん,22,23,24
"10,事務所2,13,14",20,Gさん,25,26,27

※分かりやすいように""でくくってます。
というように同じフィールド内でカンマでくくられて、

配列で分割されません。

こういった結果の場合
rs(1).AddNew
rs(1).Fields(0) = 事務所
の部分から
配列を分割できればと考えているのですが
アドバイス頂けたら助かります。
お手数ですがどうぞよろしくお願いします。

(フェンダー) 2014/10/08(水) 11:20


因みに、データベース上に
データ編集したデータを取り込んだ後
エクスポートする際に
ダブルコーテーションを外して
テキストアウトすれば
問題ないと思いますが
出来たら、データ編集の段階で
対応出来ればと考えております。
どうぞよろしくお願いいたします。

(フェンダー) 2014/10/08(水) 14:51


 ご自身で作成されたコードではないのですかね?
Sub main()
    Dim db As DAO.Database
    Dim rs(1) As DAO.Recordset
    Dim FSO As FileSystemObject
    Dim mainStream As TextStream
    Dim myData As Variant
    Dim 事務所 As String, i As Integer
    Dim cnt As Integer, vnt As Variant '★
    Set db = CurrentDb
    Set rs(1) = db.OpenRecordset("テーブル", dbOpenDynaset) 'テーブルファイルをセット
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set mainStream = FSO.OpenTextFile("C:\testout.txt", ForReading)
    Do Until mainStream.AtEndOfStream
        myData = Split(mainStream.ReadLine, ",")
        Select Case myData(0)
            Case "10"
                事務所 = myData(0) & "," & myData(1) & "," & myData(2) & "," & myData(3)
                For i = 1 To 4
                    '?
                Next
            Case Else
                rs(1).AddNew
                '★
                cnt = 0
                For Each vnt In Split(事務所, ",")
                    rs(1).Fields(cnt) = vnt
                    cnt = cnt + 1
                Next
                For i = LBound(myData) To UBound(myData)
                    rs(1).Fields(i + cnt) = myData(i)
                Next
                rs(1).Update
        End Select
    Loop
    mainStream.Close
End Sub
 
テストしてません(やる気も無い)がこんなことですか。
「テーブル」のレイアウトが分からないからアレですが。
きっと単なる枠を作っただけのテーブルなのだろうと想像はしつつ。
(ご近所PG) 2014/10/08(水) 16:29

すいません。
表記し忘れましたが空のテーブルになります。

サンプルデータを土台に
参考書などから作ってみたのですが
うまくいかない部分だけ
ご質問させて頂きました。

お手数をおかけしてますので、エラー表示は提示しませんが
エラーになります。
参考にさせて頂きます。

(フェンダー) 2014/10/08(水) 17:05


 仮に以下の部分でエラーになるなら
    For i = LBound(myData) To UBound(myData)
        rs(1).Fields(i + cnt) = myData(i)
    Next
「テーブル」のフィールド数が足りてないとかそんなところだと思います。
(ご近所PG) 2014/10/08(水) 17:11

ご連絡どうもありがとうございます。
せっかくコメント頂いたので、報告します。
ご近所PG様のおっしゃる通り
        rs(1).Fields(i + cnt) = myData(i)
で、このコレクションには、項目がありませんという
エラーでしたので
テーブルのフィールドを10フィールドぐらい増やしたのですが
同じエラーになるんですよね。
 操作方法が誤っている可能性が、あるので
またテーブルを作り直して取り込んでみます。
(フェンダー) 2014/10/08(水) 17:55

もう一度、あらためてバケットテーブルを用意しましたら
ご近所PG様のアドバイス通りで対応出来ました。

最終テストで、
10のレコードが20フィールド
20のレコードが150フィールドのテストデータを用意し
データ編集をしたところ
実行時エラー3163
指定されたデータ量がフィールドサイズを超えています。
データ量を減らし、挿入または貼り付けを行ってください。
となります。
因みにバケットテーブルは200フィールド用意してます。

下記の部分です。

rs(1).Fields(cnt) = vnt

こういった場合の、対処方法はどのようにすれば良いのでしょうか?
お手数をおかけします。

(フェンダー) 2014/10/09(木) 09:44


 記述内容からAccessのことだと思いますが、
Accessのテーブルはフィールド数の上限のほかに、
フィールドのサイズ合計という制限もあります。
 
各フィールドサイズを必要最低限に調整してみるくらいでしょうか。
 単にフィールド追加するだけだと
  データ型:短いテキスト
  フィールドサイズ:255
 となり、無駄が多い可能性がある。
 
現状調整済みで足りないなら考え方を変える必要があるでしょう。
 
そもそもの要件である最終出力物が完成すれば良いとして考えれば、
当初フェンダーさんが書かれていた
 1フィールドにカンマ区切りのデータをそのまま格納
というのも一つの手法としてはアリだと思います。
 
テーブルの定義を短いテキストではなく長いテキストとして、区分毎のフィールドを用意する……
Create Tableで表現すると
 
Create table テーブル(項目10 MEMO,項目20 MEMO);
 
等ですか。
長いテキスト型なら1GBだか2GBだかのテキストデータを格納できたと思います。
格納後に単に結合して出力すれば良いでしょう。
 
もっとも、本当に記載された要件だけで済ませて良いならDBを介さずに
処理する方がスマートなのでしょうけれども。
(ご近所PG) 2014/10/09(木) 10:38

アドバイスどうもありがとうございます。

アクセスにフィールドサイズの制限があるとは知りませんでした。

まずなぜアクセスの取り込みを選択したかといいますと

1000000行クラスだと、エクセルのセル上取込より
アクセスの方が安定するのと
そのまま取り込んでデータ編集後に
クエリを使用して
レコードの抽出を行うのに効率が良いと考えたからです。

ご近所PG様のアドバイス通り
1フィールドにカンマ区切りのデータをそのまま格納で
検証してみたのですが
事務所 = myData(0) の添え字のヶ所が
12フィールドまでしか格納できません。
こちらも
指定されたデータ量がフィールドサイズを超えています。
となります。

データ編集する前に要らないフィールドを削除する方法も
考えたのですが
すべてのフィールドにデータが入ってますので
フィールドを削ることも、出来ません。

こういったエラーが発生すると思ってませんでしたので
結果的にはVBAの入出力の方が良かったのですが・・・

ご近所PG様のアドバイス通り
Create table テーブル(項目10 MEMO,項目20 MEMO);
というような作業をやってみたいのですが
作業方法が分かりません。
急ぎではありませんので
時間がある時にでも
ご説明いただくと助かります。

(フェンダー) 2014/10/09(木) 14:38


 データを編集する前提ならこの考え方はダメだろうからこそ、サンプルコードを記述します。
きっとこのままでは答えにはなりません。
 
冗長な部分は削りました&テストデータをCドライブ直下に置くのはイヤなので
C:\tempにある事としています。
 
Sub main()
    Dim rs As DAO.Recordset
    Dim FSO As New FileSystemObject
    Dim mainStream As TextStream
    Dim 事務所 As String
    Dim strLine As String
    Set rs = CurrentDb.OpenRecordset("テーブル", dbOpenDynaset) 'テーブルファイルをセット
    Set mainStream = FSO.OpenTextFile("C:\temp\testout.txt", ForReading)
    Do Until mainStream.AtEndOfStream
        strLine = mainStream.ReadLine
        Select Case Split(strLine, ",")(0)
            Case "10"
                事務所 = strLine
            Case Else
                rs.AddNew
                rs.Fields("項目10") = 事務所
                rs.Fields("項目20") = strLine
                rs.Update
        End Select
    Loop
    mainStream.Close
    rs.Close
    MsgBox "end"
End Sub
 
そもそもフィールド数云々でのエラーはおいといて、
各フィールドに流し込むロジックが作れたのなら、
データをテーブルに流し込んでいる部分を
ファイルとして出力する形に変えてみる事を考えてみてはいかがかしらと。
ただ、データ編集が絡むとまた違うかもしれませんが。
(ご近所PG) 2014/10/09(木) 15:10

コードありがとうございます。

最終的には入出力に切り替えようと思っていたのですが
アドバイス頂いた方法でも
試してみたかったので・・・

サンプルデータの中身は
何を使ってくれという指示がありませんでしたので

10,事務所1,1,2
20,Aさん,4,5,6
20,Bさん,7,8,9
20,Cさん,10,11,12
10,事務所2,13,14
20,Dさん,16,17,18
20,Eさん,19,20,21
20,Fさん,22,23,24
20,Gさん,25,26,27

のフィールド数の少ない
データに
テーブルは多めに作って実行したところ
rs.Fields("項目10") = 事務所
rs.Fields("項目20") = strLine

このコレクションには、項目がありませんという
エラーでしたので
MsgBoxは確認できませんでした。

>きっとこのままでは答えにはなりません。

おっしゃる通りこのままでは
きりがありませんので
VBA入出力に切り替えてみようと思います。

またご相談させて頂ければありがたいです。

(フェンダー) 2014/10/09(木) 16:43


 > このコレクションには、項目がありませんというエラー
 
なぜこのエラーが出るか、そこを追求するくらいはして欲しかったけれど……
「テーブル」に「項目10」や「項目20」といったフィールドが無いから、ですよね。
 
考え方は切り替えるということですので、まぁこれはこれで。
(ご近所PG) 2014/10/09(木) 16:50

あーすいません。
そこは気がついていたのですが
項目10・項目20と書いてあったので

10と20がある項目という意味と解釈(勘違い)しましたので

rs.Fields("10") = 事務所
rs.Fields("20") = strLine
に変更してはみましたが、エラーが出ました。

せっかく作成して頂いたので
データではない
テーブルに項目10・項目20という
フィールドを追加して
もう一度ちょっとやってみます。

(フェンダー) 2014/10/09(木) 17:26


 一応前提が
    Create table テーブル(項目10 MEMO,項目20 MEMO)
にて作成されたテーブル、というつもりでしたので……
上記をクエリなりで実行すると「テーブル」が作成され、その中身は
    項目10 長いテキスト
    項目20 長いテキスト
といった2フィールドになるのです。
(ご近所PG) 2014/10/09(木) 17:35

Create table テーブル(項目10 MEMO,項目20 MEMO);に
話がつながっていたのですね。

> 一応前提が

    Create table テーブル(項目10 MEMO,項目20 MEMO)
にて作成されたテーブル、というつもりでしたので……
上記をクエリなりで実行すると「テーブル」が作成され、

このあたりの操作方法がよく分からないんです。
私は、通常作っていたバケットテーブルの1フィールド目に
項目10か項目20をセットすればいいと思っていたのですが・・・
(フェンダー) 2014/10/10(金) 09:17


 クエリで実行するが分からなければ調べるか、忘れてください。
単にテーブルを作る、それだけです。
 
今一度、先に示した通りのテーブルを作ってみてください。
すなわち
 
「テーブル」その中身は
    項目10 長いテキスト
    項目20 長いテキスト
といった2フィールド
 
です。
(ご近所PG) 2014/10/10(金) 09:25

 色々なテーブルを作ってみたのですがダメですね。

 例1 テーブルの中身 項目10 ,長いテキスト
           項目20 ,長いテキスト

      データの中身  項目10 ,長いテキスト
           項目20 ,長いテキスト

 例2 テーブルの中身 項目10 ,長いテキスト
           項目20 ,長いテキスト
           項目20 ,長いテキスト
           項目20 ,長いテキスト
           項目10 ,長いテキスト
           項目20 ,長いテキスト
           項目20 ,長いテキスト
           項目20 ,長いテキスト
           項目20 ,長いテキスト

      データの中身  10,事務所1,1,2
           20,Aさん,4,5,6
           20,Bさん,7,8,9
           20,Cさん,10,11,12
           10,事務所2,13,14
           20,Dさん,16,17,18
           20,Eさん,19,20,21
           20,Fさん,22,23,24
           20,Gさん,25,26,27 

 色々試してもこのコレクションには、項目がありませんという
 エラーですが、なにか私の設定方法は間違ってますでしょうか?

(フェンダー) 2014/10/10(金) 10:11


 中身といったから混乱してるんですかね。
テーブル定義といえば通じましたか。
 
埒が明かないので以下を実行して出来上がったテーブルを確認してください。
 
Sub maketesttable()
    CurrentDb.Execute "Create table こういうテーブル(項目10 MEMO,項目20 MEMO)"
    MsgBox "「こういうテーブル」が作成されました"
End Sub
(ご近所PG) 2014/10/10(金) 10:18

 あぁ……混乱を招いている可能性がある点をもう一つ。
 
Accessのバージョンが古い場合、
「長いテキスト」型は
「メモ」型と表示されます。
私はAccess2013を使用しているため、メモ型が「長いテキスト」と表示されています。
 
「長いテキスト」と私が表現しているのはデータ自体を抽象的に表現してのことではなく、
「数値型」のような「データ型」を示していました。
 
参考になりそうなURL追記
http://www.happy2-island.com/access/gogo05/capter20601.shtml
(ご近所PG) 2014/10/10(金) 10:33

「テーブル」その中身は
    項目10 長いテキスト
    項目20 長いテキスト
といった2フィールド

アクセス2013なら 1フィールド目を項目10の文字を取り込み形式が
長いテキスト型
アクセス2013なら 2フィールド目を項目20の文字を取り込み形式が
長いテキスト型
と解釈しました。

今まで長いテキストや、MEMOの意味が分からなかったのですが
取込の形式の事だったということで認識しました。

話を整理しますとこちらの環境はアクセス2010になりますから
1フィールド目→項目10の文字を取り込み形式がメモ型
2フィールド目→項目20の文字を取り込み形式がメモ型
という認識で確認させて頂きます。
(フェンダー) 2014/10/10(金) 12:26


Sub maketesttable()
    CurrentDb.Execute "Create table こういうテーブル(項目10 MEMO,項目20 MEMO)"
    MsgBox "「こういうテーブル」が作成されました"
End Sub

まずこちらを実行しても
MsgBox に"「こういうテーブル」が作成されました"という表示がされるだけで
実際のテーブルは作成されません。

次に私の認識が間違っていなければ
1フィールド目→項目10の文字を取り込み形式がメモ型
2フィールド目→項目20の文字を取り込み形式がメモ型
というテーブルを取り込んで

データの中身  10,事務所1,1,2
        20,Aさん,4,5,6
        20,Bさん,7,8,9
        20,Cさん,10,11,12
        10,事務所2,13,14
        20,Dさん,16,17,18
           20,Eさん,19,20,21
           20,Fさん,22,23,24
           20,Gさん,25,26,27
をセットしても
未だにこのコレクションには、項目がありませんという
エラーになってしまいます。
サンプルの実行結果のテーブルを確認できなくて
すいません。

(フェンダー) 2014/10/10(金) 13:02


 私が実行した限りでは、
上記maketesttableを実行した後は表示が更新されないようで、
F5を押すなりすると表示が更新され、作成されたテーブルを確認できると思います。
 
あるいは単にAccessDBを閉じて開き直すと、テーブルが出来ている事が確認できるでしょう。
 
 
どうも大事な事が伝わっていない気がするのですが
「項目10」と「項目20」という名称のフィールドが無いとダメなのですが、
そこは理解されてるでしょうか。
勝手につけた名前では通りません。
 
もしフェンダーさんがコードを
    rs.Fields("10") = 事務所 
    rs.Fields("20") = strLine
と直しているのなら、
テーブル定義は
    10 メモ型
    20 メモ型
です。
Create Table文で示すなら
    Create table テーブル(10 MEMO,20 MEMO)
です。
(でも数字だけのフィールド名は推奨されていないと記憶しています……)
 
もう一例書きますか。
 
もしコードが
    rs.Fields("フィールドA") = 事務所 
    rs.Fields("フィールドB") = strLine
と書かれているなら、テーブル定義は
    フィールドA メモ型
    フィールドB メモ型
です。
Create Table文で示すなら
    Create table テーブル(フィールドA MEMO,フィールドB MEMO)
です。
 
ついでに
C:\temp\testout.txt
の中身は
 
10,事務所1,1,2
20,Aさん,4,5,6
20,Bさん,7,8,9
20,Cさん,10,11,12
10,事務所2,13,14
20,Dさん,16,17,18
20,Eさん,19,20,21
20,Fさん,22,23,24
20,Gさん,25,26,27
 
でテスト済みです。
実行した結果のテーブルの中身は
 
項目10                項目20
10,事務所1,1,2      20,Aさん,4,5,6
10,事務所1,1,2      20,Bさん,7,8,9
10,事務所1,1,2      20,Cさん,10,11,12
10,事務所2,13,14  20,Dさん,16,17,18
10,事務所2,13,14  20,Eさん,19,20,21
10,事務所2,13,14  20,Fさん,22,23,24
10,事務所2,13,14  20,Gさん,25,26,27
 
です。
(ご近所PG) 2014/10/11(土) 00:34

一度閉じるのわすれました。
F5でも更新されるんですね。

(でも数字だけのフィールド名は推奨されていないと記憶しています……)
 
コードとテーブルの数値は共通を
意識して、項目でも
試したと思いますが
あくまで記憶です。
数値だけのフィールド名は
推奨されてないとは、
知らなかったです。
いずれにしても
私の操作方法にあやまりがあります。

平日でないと、確認出来る環境が用意出来ないので
後日、ご報告させていただきます。
(フェンダー) 2014/10/12(日) 08:01


ご回答遅くなりました。

Sub maketesttable()

    CurrentDb.Execute "Create table こういうテーブル(項目10 MEMO,項目20 MEMO)"
    MsgBox "「こういうテーブル」が作成されました"
End Sub
で、こういうテーブル拝見させて頂きました。

F5かソフト再起動で確認できました。
確認させて頂いてからやっとわかったのですが
私は、配列に項目10と項目20を入力していたのですが
フィールド名を変更していることに気がつきませんでした。

コードをよく見ると
rs.Fieldsと書いてありますよね。

実際のフィールドが200項目ぐらいあるテストデータも
無事、テキストアウト出来ました。
これから細かい検証が必要ですが
いまのところ
わざわざVBAに書き直す必要はありません。
また細かいテストで、エラーが発生した場合は
VBAで書き直すか
またご相談させてください。
長い間、お付き合いいただきまして、本当にどうもありがとうございました。

(フェンダー) 2014/10/14(火) 09:01


 とりあえずこちらが意図するところまでたどり着けたようでよかったです。
少々忙しくなってきたので中々こちらの掲示板を見ることが出来ませんが、
上記ままで使用した場合に起こりうる可能性のある問題をひとつだけ。
 
現在はデータを突っ込んで再度取得して出力している形ですが、その場合
データの並び順が維持されるかが疑問です。
INとOUTでデータの並び順を気にする必要がないなら構いませんが
順序が大事な場合、ソートのためのキーとなるフィールド(行番号など)を
同時にテーブルへ書き込む事が必要と思っています。
 
以上、ちょっとした老婆心でした。
今後は回答できるか分からないため、何かあればどなたかのフォローお願いします。
(ご近所PG) 2014/10/15(水) 14:51

 よくよく考えてみたらもはやExcelではなくAccessの話になってました。
ここでは回答を得られない可能性が高いかもしれませんね。
もちろんAccessを始めデータ処理やらDBにも精通している方が多くいらっしゃるので
答えてくれる人は居ると思いますが、あくまでも
「エクセルの学校」という事を念頭に置いておかねば……(と自戒)
(ご近所PG) 2014/10/15(水) 15:04

わざわざ、これからの不具合を想定したアドバイスどうもありがとうございます。
レコードの並びが変わるのは、対策が必要ですが
多少のフィールドの並びが変わるのは
問題ありません。
あまり変わりすぎると、印刷指示をするときにわけがわからなくなってしまいますが・・・

追加*****************************
レコードの並びの問題であれば
どのみち、郵便番号をキーに
郵便番号の若い順番にソートしてしまうので問題はないかと思います。
追加*****************************

とりあえず私も検証する時間がありませんので
時間が空いたときにでも
各配列のフィールド及びレコード順に連番を振って
問題ないか検証はしてみる予定です。
そういえば、アクセスの話になってましたので
VBのコードに関して、もしくは
処理方法による考え方等でもアドバイスいただければと
思っております。
どうもありがとうございました。

(フェンダー) 2014/10/15(水) 21:27


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.