Microsoft Access 掲示板

表をアクセスに取り込みたい

17 コメント
views
4 フォロー

テキストボックスからインポート操作

現在、ワードの表をアクセスに取り込む問題で苦戦しております。
ワードから表をコピペして、上記で教えていただいた方法でテーブルに取り込んでいたのですが
上記コードでは解決できない表が出てきました。

例えばエクセルに貼り付けると下記のような表です。
(数字で表していますが、実際は数字の中に文字列が入っています)
※1~4はワードでは同じセルに格納されているがエクセルでは行が分かれる。行数に変動有。
 5~6はワードでは同じセルに格納されているがエクセルでは行が分かれる。行数変動なし。
 7はワードでは同じセルに格納されているがエクセルでは1~4行目のセルの結合になっている。
※実際はこれと同じような表が縦に並んでいる状態だが
 まとめて取り込みは厳しそうなので、せめて1データずつ取り込みたいと思っている。

1 5 7
2 6
3
4

●どのように取り込みたいか

①1,2,3,4,5,6,7を1つのレコードとして取り込みたいです。
その際、1~4、5~6を同じフィールドに入れたいのですが
1の文字列は複数可変のタブ区切りが入ってます…
また、1~4の行数も可変です。
余裕を持たせてフィールドを作成することはできますが、その場合、5番目以降をきちんと既定のフィールドに
格納する方法がわかりません・・

以上、わかりづらくてスミマセン。よろしくお願いいたします。

セロハン
作成: 2020/10/23 (金) 17:57:33
最終更新: 2020/10/23 (金) 19:36:20
通報 ...
1
セロハン 2020/10/23 (金) 19:55:56 1d451@2b9f5

xmlに変換して確認したのですが、

で区切られている部分をフィールドに分けて

今回の件がwordの中の、表の中身を抜き取ってアクセスにインポートしたいという作業になるので
一旦xmlに変換してそこから表の部分だけコピペというのも手間がかかるように思い、
やはりwordから表の部分を目視でコピペで完結したいのですが…VBAでの処理は難しいでしょうか…?

2
セロハン 2020/10/23 (金) 19:57:48 1d451@2b9f5 >> 1

↑タグ部分がすっかり消えていたので書き直します

xmlに変換して確認したのですが、

<td>

で区切られている部分をフィールドに分けて

<tr>

で区切られている部分をテーブルに分けたいです。

今回の件がwordの中の、表の中身を抜き取ってアクセスにインポートしたいという作業になるので
一旦xmlに変換してそこから表の部分だけコピペというのも手間がかかるように思い、
やはりwordから表の部分を目視でコピペで完結したいのですが…VBAでの処理は難しいでしょうか…?

3

ひょっとして、Wordの表データは、セル内で改行があるものですか。
だとすると、テキストボックスにコピペしたものでは、ちょっと難しいですね。
セル内改行とレコード区切りの改行の区別がつかないので。

下記にWordの表をエクセルに取りこむVBAコードのサンプルがあります。

【VBA】Word文書内の表をエクセルに取り込む | あじゅWeb

Tableオブジェクトを使って、Wordの表をExcelに貼り付ける:VBA/マクロ便利Tips - @IT

上記をAccess用改造すれば、ワードファイルのパスと何番目のテーブルかを指定すれば取り込むことは可能だと思います。

4
セロハン 2020/10/24 (土) 01:48:13 f1ed8@2b9f5

おっしゃるとおり、セル内にも改行があります…
やはりレコード区切りの改行とは区別がつかないのですね。ワードからエクセルにはうまく貼り付けられるから、何かしら区別の方法があるのかもと思っていました…
accessにはxmlからなんとか抜き出す方法を考えてみたいと思います。
wordからexcelのvbaも参考にさせていただきます。ありがとうございました。

5
hiroton 2020/10/26 (月) 10:08:53 8d8c2@f966d

めちゃくちゃめんどくさそうですがクリップボードのデータを直接取得してあれこれやればできないこともなさそうな感じはありました

クリップボードを操作する方法 (YU-TANG's MS-Access Discoveryさん)
※すでにページはないのでInternet Archive(web.archive.org)です

Wordでコピーした状態からだとHTMLDocumentとしてアクセスすることができ、テーブル構造を取得できるようです
ただし、TABとか改行とかはHTML用に変換されてしまうようなので内容を解析して再変換みたいなことをする必要がありそうです

6
セロハン 2020/10/26 (月) 13:18:22 0029a@1c915 >> 5

ありがとうございます!!めんどくさそうということなので、時間を取って確認させていただきます。
ありがとうございました。

7
セロハン 2020/10/26 (月) 13:26:33 0029a@1c915

この件と絡み、別データになるのですが、改行を外して対応したいデータについて
列数が定数のデータがあり、以前教えていただいたVBAを修正して対応できないかと考えたのですが
うまくいきません。

Private Sub AddData(tblname As String, ByRef s As String)
    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    Dim a, i As Long, j As Long
    Dim Datas

    Set db = CurrentDb
    Set rs = db.OpenRecordset(tblname)
    a = Split(s, vbNewLine)
    For i = 0 To UBound(a)
        Datas = Split(a(i), vbTab)
        rs.AddNew
        On Error Resume Next
        For j = 0 To UBound(Datas)
            rs(j) = Datas(j)
        Next
        On Error goto 0
        rs.update
    Next
End Sub

Private Sub データ追加_Click()
    Call AddData(Me.txtテーブル名, Me.txtデータ)
End Sub

以前hatena様に教えていただいたVBAです。
こちらの「UBound(a)」の部分を変数にして
下記修正してみたのですが、うまく動きません。
「インデックスが有効範囲にありません」とエラー。

Private Sub AddData(tblname As String, ByRef s As String, iUp As Long)
    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    Dim a, i As Long, j As Long
    Dim Datas

    Set db = CurrentDb
    Set rs = db.OpenRecordset(tblname)
    a = Split(s, vbNewLine)
    For i = 0 To iUp
        Datas = Split(a(i), vbTab)
        rs.AddNew
        On Error Resume Next
        For j = 0 To UBound(Datas)
            rs(j) = Datas(j)
        Next
        On Error GoTo 0
        rs.upDate
    Next
End Sub

Private Sub データ追加_Click()
    Call AddData(Me.txtテーブル名, Me.txtデータ,列数)
End Sub

スミマセン。教えていただけると助かります。

8
セロハン 2020/10/26 (月) 13:36:46 0029a@1c915

あ、ちなみにiUpをvariantにしたら、引数で「UBound(a)」としても対応できますでしょうか。
VBAの初歩的な質問で恐れ入ります…

11
hiroton 2020/10/26 (月) 14:20:58 8d8c2@f966d >> 8

VBA記述的な話

a = Split(s, vbNewLine)は改行で区切りにした配列なのでUBound(a)は行数=レコード数ですね。列数に対応しているのはUBound(Datas)のほうです

aAddData()内でDim aした変数なのでデータ追加_Click()では使えないです。やるとすれば

Private Sub データ追加_Click()
    Const 列数 = 10 '//列数固定データの列数
    Call AddData(Me.txtテーブル名, Me.txtデータ, 列数)
End Sub

のように定数を宣言してあげる形でしょうか。このくらいならわざわざ宣言しなくてもいいですが


個人的な感想だとUBound(Datas)iUpに置き換えるメリットは感じないですね。汎用性が落ちる分やらなくていいんじゃないかなと

12
セロハン 2020/10/26 (月) 14:34:33 0029a@1c915 >> 11

>列数に対応しているのはUBound(Datas)のほうです

本当ですね…すみません。

>aはAddData()内でDim aした変数なのでデータ追加_Click()では使えないです。

なるほど…
取り込みデータにいくつか種類があり、ボタンを分けているのですが、
全部同じ汎用関数で行けるかなとかんがえていました
分けた方が良さそうですね、勉強になりました。ありがとうございます。

9

列数が固定でも、例えば最後の列のセルや1列目のセルに改行がある場合、どの改行がレコード区切りなのか判断つかないので、無理ですね。例えば1列目がIDとかで改行がないということが保障されているなら方法はありそうです。

10
セロハン 2020/10/26 (月) 14:15:55 0029a@1c915 >> 9

紛らわしくてすみません。
これは前回質問したものとは別データになり、
セル内に改行が存在しないデータになります。

セル内には改行が存在しないのですが、同じレコード内の列の区切りで途中で改行が入っているので
一括で改行を外して、固定の列数でレコードを区切りたく思っています。

いろんな種類のデータがあり、明確に分別できるのでそのように取り扱いたく…紛らわしくてすみません。

13

セル内には改行が存在しないのですが、同じレコード内の列の区切りで途中で改行が入っているので
一括で改行を外して、固定の列数でレコードを区切りたく思っています。

ちょっと、どのようなデータなのかこの説明だけではわかりません。
「レコード内の列の区切りで途中で改行が入っている」というのが「セル内に改行が入っている」とどう違うのか分かりません。

ワードの表ではないのですか。
ワードの表ならば、前の回答で紹介した下記のリンク先の方法で
エクセルのセルに代入する部分を、テーブルに代入するように書き換えるだけです。

【VBA】Word文書内の表をエクセルに取り込む | あじゅWeb

これが比較的シンプルで確実な方法だと思います。

14
hiroton 2020/10/26 (月) 14:48:03 8d8c2@f966d

単純に1データ1行のテキストデータですかね?レコード(列数)という情報なしの

Private Sub AddData2(tblname As String, ByRef s As String, colCount As Long)
    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    i As Long, j As Long
    Dim Datas

    Set db = CurrentDb
    Set rs = db.OpenRecordset(tblname)
    Datas = Split(s, vbNewLine)
    i = 0
    Do While i <= UBound(Datas)
        rs.AddNew
        On Error Resume Next
        For j = 0 To colCount
            rs(j) = Datas(i)
            i = i + 1
        Next
        On Error GoTo 0
        rs.upDate
    Next
End Sub
15

ワードの表データではなく、別のテキストデータということなのかな。
だとしたら、まったく別の質問になるので新規に質問を立ててもらった方がいいですね。
あとから見た人にとっても利用しやしすですので。

16
セロハン 2020/10/26 (月) 15:30:41 0029a@1c915 >> 15

スミマセン!同じくワードの表からテキストボックスへのコピペなのですが、セル内に改行がなく、レコード途中で改行があったので、下記加工して、1行のテキストのようにして扱っていました。そのことを書けばよかったです。
新規スレ立てようか悩んだんですが、わかりづらくなってしまい申し訳ありません。

Private Sub btn取込_Click()
    Dim 取り込みデータ As String
    取り込みデータ = Me.txtボックス
    取り込みデータ = Replace(取り込みデータ, vbCrLf, vbTab)
      Call AddData2(Me.txtテーブル名, Me.txtデータ,列数)
End Sub

上記の上、教えていただいたコードを部分的に修正してうまく動きました!
他の方が参考にされるかもしれないので載せておきます。
大変助かりました。ありがとうございました!

Private Sub AddData2(tblname As String, ByRef s As String, colCount As Long)
    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    Dim i As Long, j As Long
    Dim Datas

    Set db = CurrentDb
    Set rs = db.OpenRecordset(tblname)
    Datas = Split(s, vbTab)
    i = 0
    Do While i <= UBound(Datas)
        rs.AddNew
        On Error Resume Next
        For j = 0 To colCount
            rs(j) = Datas(i)
            i = i + 1
        Next
        On Error GoTo 0
        rs.upDate
    Loop
End Sub
17
セロハン 2020/10/26 (月) 15:42:48 0029a@1c915

ごめんなさい…
VBAに間違いがあります。修正します。

Private Sub btn取込_Click()
    Dim 取り込みデータ As String
    If IsNull(Me.txtデータ) Then
    MsgBox "テキストボックスが空です。"
    Else
    取り込みデータ = Me.txtデータ
    取り込みデータ = Replace(取り込みデータ, vbCrLf, vbTab)
        Call AddData2(Me.txtテーブル名, 取り込みデータ, 列数)
    End If