AccessVBA初心者です。いつもお世話なっております。

環境 OSーXPsp2 office2003
テーブル1とテーブル2あって、テーブル1にデータはいってます。テーブル2は空です。
ACCESS VBA DAOで
テーブル1のデータの[店名]、[氏名]を テーブル2に横に追加していきたいです。
テーブル2 構造
ID(オートナンバー)  [店名]1 [氏名]1 [店名]2 [氏名]2 
---------------------------------------------------------

テーブル1のデータ
ID(オートナンバー)  [店名] [氏名]  
1           A    Aさん  
2           B     Bさん   
3           C     Cさん   
4   D       Dさん
-----------------------------------------------------
結果
テーブル2
ID(オートナンバー)  [店名]1 [氏名]1 [店名]2 [氏名]2 
1            A   Aさん   B   Bさん
2            C   Cさん   D   Dさん

ACCESS VBAでの書く方
教えてください。宜しくお願い足します。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

> すこし説明のほうお願いできますか。



>    If (iFlg = 0) Then
>      rsTo.AddNew
>      rsTo("店名1") = rsFrom("店名")
>      rsTo("氏名1") = rsFrom("氏名")
>    Else
>      rsTo("店名2") = rsFrom("店名")
>      rsTo("氏名2") = rsFrom("氏名")
>    End If
>    iFlg = 1 - iFlg
>    If (iFlg = 0) Then
>      rsTo.Update
>    End If
>    rsFrom.MoveNext
>  Wend
>  If (iFlg <> 0) Then
>    rsTo.Update
>  End If

では、拙い説明になりますが上記部分について以下に。


iFlg は、0か1を取るようにしています。
iFlg = 1 - iFlg  これで、0、1を反転させています。

0の場合、rsTo.AddNew 処理し、iFlg を1に
1の場合、既に rsTo.AddNew しているので、代入だけし、iFlg を0に

代入処理(前半のIF)後、iFlg が0の場合、2つの処理が終わっているので rsTo 側を確定(Update)

While を抜けた後、iFlg が0でなければ、奇数レコードを処理して確定していない状態なので Update


※ この書き方にしていると、後の修正が楽です(私にとっては)
例えば、店名3, 氏名3 をテーブル2に追加して3組の列にしたいとなった場合、

>    If (iFlg = 0) Then
>      rsTo.AddNew
>      rsTo("店名1") = rsFrom("店名")
>      rsTo("氏名1") = rsFrom("氏名")
>    Else
>      rsTo("店名2") = rsFrom("店名")
>      rsTo("氏名2") = rsFrom("氏名")
>    End If
>    iFlg = 1 - iFlg

↓以下の変更で対処できます(★部分変更)

>    If (iFlg = 0) Then
>      rsTo.AddNew
>      rsTo("店名1") = rsFrom("店名")
>      rsTo("氏名1") = rsFrom("氏名")
    Else If (iFlg = 1 ) Then ' ★
>      rsTo("店名2") = rsFrom("店名")
>      rsTo("氏名2") = rsFrom("氏名")
>    Else
      rsTo("店名3") = rsFrom("店名") ' ★
      rsTo("氏名3") = rsFrom("氏名") ' ★
>    End If
    iFlg = (iFlg + 1) Mod 3 ' ★

この場合 iFlg は、0,1,2の値をとります。
    • good
    • 0
この回答へのお礼

 ありがとうございます。大変勉強になりました。後の修正についても説明があって、大変うれしいです。
 順番意識、後処理に意識する。これもこの間質問していく中で得た貴重なアドバイスだと思っています。
 

お礼日時:2009/05/15 21:32

バッチ処理ならDAOでテーブル1を読んで、テーブル2のフィールドに書き、フィールドのインデックス番号をどんどん進めれば仕舞いではないか(レコードは進めない)。

どの点を聞いているのか。WEBのコード例でも(途中まででも)やってみたのか。丸投げ的質問。
フィールドを都度増やす、CreateFieldは
http://www.accessclub.jp/bbs2/0077/beginter24062 …
を参照。
ーーー
データを横に(フィールドを増やして)記録していくなんて、アクセスでは(エクセルでもそうだが特にアクセスは)非常識だ思うよ。
どれくらい量が有るかに拠るが。
ーー
コンピュタ処理の設計思想は、初心者の間は十分気をつけること。
そうする理由が薄弱だったり、とりあえず思い付いたのでそれでやる、が多くなる。後の処理でまた困ることが多い。
この質問も全貌(その後のテーブル2の使い道、役立て方など)を質問に書かず、「やりたいのだ」「その路線でのやり方を教えてくれればよい」と言う風に感じる。
ーー
それにイベント(バッチ処理の反対)処理の臭いがするが(テーブルにデータが追加されると質問のテーブル2に増やしていく)それは初心者が出来ることではないと思うが。
私見なので諸賢のご批判を乞う。
    • good
    • 0
この回答へのお礼

 勉強の方向性と質問の仕方についてアドバイスしてくださって、ありがとうございます。
 実際の業務にこういう例がたまたまあるようです。量的に何万件かぐらいだそうです。
 後処理のことの話でましたが、貴重なアドバイスとして受け止めます。前回質問をしたとき、順番に意識していないことから初心者の証拠など、厳しい意見を書いた人もいました。
  

お礼日時:2009/05/15 21:28

> [店名]1 [氏名]1 ・・・



[店名1] [氏名1] ・・・ ということで


DAOは不慣れなので、参考程度で。

Private Sub Sample1()
  Dim rsFrom As DAO.Recordset
  Dim rsTo As DAO.Recordset
  Dim iFlg As Integer

  iFlg = 0
  Set rsFrom = CurrentDb.OpenRecordset("SELECT * FROM テーブル1") '★
  Set rsTo = CurrentDb.OpenRecordset("SELECT * FROM テーブル2")
  While (Not rsFrom.EOF)
    If (iFlg = 0) Then
      rsTo.AddNew
      rsTo("店名1") = rsFrom("店名")
      rsTo("氏名1") = rsFrom("氏名")
    Else
      rsTo("店名2") = rsFrom("店名")
      rsTo("氏名2") = rsFrom("氏名")
    End If
    iFlg = 1 - iFlg
    If (iFlg = 0) Then
      rsTo.Update
    End If
    rsFrom.MoveNext
  Wend
  If (iFlg <> 0) Then
    rsTo.Update
  End If
  rsFrom.Close
  rsTo.Close
  Set rsFrom = Nothing
  Set rsTo = Nothing
End Sub


※ ★でレコード順を追加指定してください。
 ( 最後に ORDER BY ID とか、得たい順を)

この回答への補足

早速テストしてみたら、結果はぴったりでした。

If (iFlg = 0) Then


iFlg = 1 - iFlg
    If (iFlg = 0) Then
      rsTo.Update
    End If
    rsFrom.MoveNext
  Wend
  If (iFlg <> 0) Then
    rsTo.Update
  End If
この部分どうしでも解読できません。どうしても、知りたいので、
すこし説明のほうお願いできますか。動いたわけを。。。

補足日時:2009/05/15 18:06
    • good
    • 0

う~ん?べたですが・・・



クエリで

SELECT
DLookUp("店名","テーブル1","ID = " & [NewID]*2-1) AS 店舗1,
DLookUp("氏名","テーブル1","ID = " & [NewID]*2-1) AS 氏名1,
DLookUp("店名","テーブル1","ID = " & [NewID]*2+0) AS 店舗2,
DLookUp("氏名","テーブル1","ID = " & [NewID]*2+0) AS 氏名2
FROM (SELECT Int(([id]+1)/2) AS NewID FROM テーブル1 GROUP BY Int(([id]+1)/2)) AS UsTable;

な、感じ・・・これを追加クエリで挙動させるとか?
表示上の話だけなら、レポートのレイアウトの行列設定を使用するのですが・・・
    • good
    • 0
この回答へのお礼

ありがとうございます。これも大変勉強になりました。

お礼日時:2009/05/15 18:11

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QエクセルVBAでファイルを連続して処理する方法は

エクセルVBAで、エクセルファイルを開いた状態で特定処理を行う仕組みを作りました。
ただ、複数のファイルを処理したいのですが、いちいちファイルを開いてから処理しなければならないため効率が今ひとつです。
ファイル名称をテーブル化するなどして、一気に連続して処理するようにしたいのですが、どのように行えばいいでしょうか。

また、処理したいのは、更新日付が一定日以降のエクセルファイルです。
更新日付と対象ファイルのフォルダーを指定すれば、更新日がそれ以降のファイルを検索し、それが順次処理されていくようなVBAをつくりたいと考えています。

部分的にでもよいので、どなたか分かる方、教えてください。
ちなみにエクセルのバージョンは2000です。
よろしくお願いします。

Aベストアンサー

> 選択フォルダのサブフォルダをのものも含むようにはできないでしょうか。

再帰処理すればできますよ。

Microsoft Scripting Runtime を参照してから、次のコードを試してみて
下さい。
取り急ぎで書いたので、エラーがあるかもしれませんが。。。

まあ、環境によっては使えませんし、推奨はできないのですが、FileSearch
を使ってもサブフォルダを含めた検索はできます。調べればサンプルはすぐ
でてくると思いますよ。

ご参考までに。

Private mDateFilter As Date

Sub フォルダ内のXLSファイル順次処理()

  Dim fso As FileSystemObject
  Dim sDir As String
  
  ' // 日付のフィルタ条件設定 例)10日前の 0:00 以降更新のファイルを対象とする場合
  mDateFilter = DateAdd("d", -10, Date) + TimeValue("00:00:00")

  ' // 対象ファイルのあるフォルダを指定
  sDir = BrowseForFolder()
  If Len(sDir) = 0 Then
    Exit Sub
  End If

  Set fso = CreateObject("Scripting.FileSystemObject")
  
  Dim fld As Folder
  Dim iRes As Integer
  
  If fso.FolderExists(sDir) Then
    Set fld = fso.GetFolder(sDir)
    iRes = 0
    If fld.SubFolders.Count > 0 Then
      iRes = MsgBox("サブフォルダも検索しますか?", _
             vbYesNoCancel Or vbInformation)
    End If
    Select Case iRes
      Case vbYes:  Call FindFiles(fld, True)
      Case vbNo, 0: Call FindFiles(fld, False)
      Case Else:  ' // User Cancel
    End Select
  End If
  
  Set fld = Nothing
  Set fso = Nothing


End Sub

' // XLS ファイルを検索するサブプロシージャ
Private Sub FindFiles( _
  ByRef fld As Folder, _
  ByVal fCheckSubfolders As Boolean _
)

  ' // ファイルへの処理
  Dim f   As Object
  For Each f In fld.Files
    If f.Name Like "*.xls" And f.Name <> ThisWorkbook.Name Then
      If f.DateLastModified >= mDateFilter Then
        ' // 処理例
        Call MainProc(f)
      End If
    End If
  Next

  ' // サブフォルダ検索オプション
  Dim subFolder As folder
  If fCheckSubfolders Then
    ' // 再帰呼び出し
    For Each subFolder In fld.SubFolders
      Call FindFiles(subFolder, True)
    Next
  End If

End Sub

' // メイン処理 -- FindFiles から順次呼び出されます
Sub MainProc(ByRef f As file)

  ' // ここにご自分で書いたプロシージャを
  ' // とりあえず、セルにでも書き出してみます
  Dim i As Long
  i = Cells(Rows.Count, "A").End(xlUp).Row + 1
  Cells(i, "A").Value = f.Name
  Cells(i, "B").Value = f.DateLastModified

End Sub

' // フォルダ選択ダイアログ
Private Function BrowseForFolder() As String

  Const BIF_RETURNONLYFSDIRS = &H1

  Dim fld As Object
  Set fld = CreateObject("Shell.Application") _
       .BrowseForFolder(0&, "選択します", BIF_RETURNONLYFSDIRS)
  If Not fld Is Nothing Then
    BrowseForFolder = fld.Self.Path
  End If
  Set fld = Nothing

End Function

> 選択フォルダのサブフォルダをのものも含むようにはできないでしょうか。

再帰処理すればできますよ。

Microsoft Scripting Runtime を参照してから、次のコードを試してみて
下さい。
取り急ぎで書いたので、エラーがあるかもしれませんが。。。

まあ、環境によっては使えませんし、推奨はできないのですが、FileSearch
を使ってもサブフォルダを含めた検索はできます。調べればサンプルはすぐ
でてくると思いますよ。

ご参考までに。

Private mDateFilter As Date

Sub フォルダ内のXLS...続きを読む

QOutlookで[全員に返信]をクリックすると、[宛先]と[CC]をす

Outlookで[全員に返信]をクリックすると、[宛先]と[CC]をすべて[CC]に入るように設定。

今までOutlookずっと愛用していますが、現在は最新版のOutlook2010を使用してます。

[全員に返信]をクリックすると、元メールの[送信元]と[宛先]が新メールの[宛先]に変わり、[CC]はそのまま引継ぎますが、元メールの[送信元]と[宛先]と[CC]を全部[CC]に入るように設定などありますか。

または、[送信元]だけを[宛先]にして、ほかはすべて[CC]に入ってもいいですが。

Aベストアンサー

>[全員に返信]をクリックすると、元メールの[送信元]と[宛先]が新メールの[宛先]に変わり、[CC]はそのまま引継ぎます

これって、Microsoftのメールソフトの仕様ですかね。
自分が受信したメールの宛先やCCであっても、Outlook Expressもそうなるようです。

私のメインのThunderbirdでは、自分が複数の宛先やCCに含まれている場合でも、それらの受信メールから「全員に返信」で、受信メールの「送信元」のみが、返信メールの宛先に入り、他の「宛先」や「CC」はすべてCCに表示されます。

>[送信元]だけを[宛先]にして、ほかはすべて[CC]に入ってもいいですが。

この部分での方法は、返信メールの宛先欄で、送信元以外をドラッグして選択して右クリックから切り取り、CC欄に右クリックから貼り付けするしかないと思います。

QエクセルVBA 2千万行のCSVファイルを開きたい

上から順に読み込み、順次処理していき最終的には全部処理します。CSVファイルは読むだけです。

やり方はいくつか考えられます。
1
100万行ずつシートに読み込み、終わったら次を読み込む。CSVファイルは開きっぱなし。

2
100万行ずつのエクセルファイルに分割し、順次開いて処理。ファイル開閉に時間がかかる

3
2千万行の巨大な配列に代入し、順次処理。
CSVファイルは閉じることが出来る。

3がいいように思えますが、どうでしょうか?使用メモリは1と同じですか?

Aベストアンサー

> 懸念点は、最初から最後まで巨大なCSVファイルを開いたまま処理することです。

それに関しては問題ないです。VBAのOpenでファイルを開いた場合、実は一切読んでいません。今何行目を読んでいるかを示すカウンタを用意するだけです。またLine Inputで読み込む場合も、今操作している一行しか相手にしません。

だからこそ、実装している物理メモリ量をはるかに超えるサイズのファイルを扱っていても、仮想メモリのお世話にならずに済むわけです。

なので懸念材料はそこではなく、分割処理することによってデータ同士の断絶が起きると言うか、連続性がなくなることでしょうか。最初の100万行の固まりと、次の100万個の固まりには全くつながりがないことになるので。

Qアクセスで複数テーブルをひとつにする方法 以下3つのテーブルがあります。 Aテーブル Bテーブル C

アクセスで複数テーブルをひとつにする方法

以下3つのテーブルがあります。
Aテーブル
Bテーブル
Cテーブル
共にフィールド数、フィールド名は共通です。
3つのテーブルのレコードをまとめてDテーブルを作る場合はどのように操作するのでしょうか?

Aベストアンサー

「ユニオンクエリ」について調べてください。

QVBAからファイルをセル入力から開く方法

VBAからファイルをセル入力から開く方法

だれかご教授頂けませんでしょうか?VBAからエクセルファイルを開こうとしています。
そこでシート1のA1セルにファイル名を記述してあり、そのファイル名からファイルを開く事は出来ますでしょうか?
何か良い方法がありましたら教えて頂きたいのですが。

Aベストアンサー

下記で試してください。
パス名の最後には\を付けるようにしてください。

Workbooks.Open "D:\ABC\" & Sheets("シート1").Range("A1").Value


ワークシートのイベントを使う方法も考えられると思います。
BeforeDoubleClickイベント辺りを使って
ファイル名セルをダブルクリックすれば

Excel(エクセル) VBA入門:ワークシートのイベント
http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/vba_event.html

Q[Access] 2つのテーブルを1つに集計したい

アプリケーションのライセンス数のカウントをしています。
下記のように、既に購入済みアプリを場所毎にカウントしているテーブルAと、現在使用しているアプリ数を場所毎にカウントしているテーブルBがあります。
クエリ(でなくてもいいのですが)を使用して一番したの<最終的に欲しいクエリ>のような形にしたいのですが、どのようにしたらいいでしょうか。。

アドバイス宜しくお願いしますm(_ _)m

<テーブルA>
アプリ場所所持
=====================
A東京10
A大阪20
A京都8
B東京20
B大阪21
B京都18
C東京8
C大阪5
C京都10

<テーブルB>
アプリ場所使用
=====================
A東京5
A大阪18
A京都7
B東京18
B大阪21
B京都15
C東京4
C大阪3
C京都9

<最終的に欲しいクエリ>
アプリ場所所持使用
=============================
A東京105
A大阪2018
A京都87
B東京2018
B大阪2121
B京都1815
C東京84
C大阪53
C京都109

アプリケーションのライセンス数のカウントをしています。
下記のように、既に購入済みアプリを場所毎にカウントしているテーブルAと、現在使用しているアプリ数を場所毎にカウントしているテーブルBがあります。
クエリ(でなくてもいいのですが)を使用して一番したの<最終的に欲しいクエリ>のような形にしたいのですが、どのようにしたらいいでしょうか。。

アドバイス宜しくお願いしますm(_ _)m

<テーブルA>
アプリ場所所持
=====================
A東京10
A大阪20
A京都8
B東京20
B大阪2...続きを読む

Aベストアンサー

必ずテーブルAとBが一致する項目があることが前提です
クエリー編集画面でテーブルAとBを追加します
テーブルAアプリ列と テーブルBアプリ列を繋ぎます
テーブルA場所列と テーブルB場所列を繋ぎます
後は下の表示列欄にアプリ列(テーブルA、Bどちらでも可)を追加
場所列(テーブルA、Bどちらでも可)を追加
テーブルAの所持列、テーブルBの使用列を追加すれば
良いと思います。

QEXCEL VBA で現在開いているブックのファイル名を取得する方法

EXCEL2003 VBAで業務を簡素化するために、現在開いているブックのファイル名を取得する方法が分かりません。
作業手順をマクロを使って処理していますが、オリジナルのワークブックをファイル名を変えて保存し、以後、このワークブックを読み込んで使用しています。
このときのVBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり、以後の業務に使用できません。
常にファイル名を取得出来るVBAをどなたか、教えて下さい。

Aベストアンサー

>現在開いているブックのファイル名
 ちょっと曖昧な表現かなぁという気もいたしますが、VBAが書いてあるブックのブック名は
ThisWorkbook.Name
で、現在 "アクティブにして" 操作対象になっているブックの名前は
ActiveWorkbook.Name
ですね。

 しかし、
>VBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり
というような文脈からすると、
ThisWorkbook.Name
の方ですかね。

QAccess テーブルAにテーブルBのデータを追加

Accessで、テーブルAにテーブルBのデータ(全部)を追加したいです。
初歩的な質問でスミマセン。

Aベストアンサー

簡単にやるにはテーブルBのクエリをクエリウィザードで作り そのクエリをテーブル追加クエリにすれば簡単にできます。
クエリウィザードで作ったテーブルBのクエリをデザインビューで開きメニューのクエリにある追加を選ぶかデザインビュー上で右クリックでクエリの種類から追加を選びます。
追加を選ぶとテーブルを選択できますのでそこでテーブルAを選びます。テーブルBとテーブルAのフィールド名が同じならレコードの追加欄にフィールド名が自動で表示されます。フィールド名が異なる場合はレコードの追加欄をクリックしてテーブルAの追加先のフィールド名をそこで指定します。
クエリを保存します。
保存したクエリをダブルクリックすればテーブルBのレコードがテーブルAに全部追加されます。

Q他のExcelファイルのVBAコードを検索したい

他のExcelファイルに書かれたVBAコードに、ある特定のキーワード(パス名など)が使われているかを自動的に調べるためのVBAを書きたいと思っています。

仕事で使っているマクロが書かれたExcelファイルからある特定の処理をしているマクロを含むものを検索したいのですが、検索するExcelファイルが膨大なため、順番にExcelファイルを開いてVBAコードをチェックしていく工程をマクロ化したいのです。ファイルを順に開いていく処理はマクロ化できるのですが、書かれたVBAコードのチェックをどうしたらよいか悩んでいます。

「VBAコードに対して検索する」または「VBAコードを1行ずつ変数に代入する」、「モジュールシートをテキストファイルに出力する」などの処理が自動化できれば対応できそうなのですが、そのような処理をExcelVBAで作成できるでしょうか。

なお環境はWindowsXPのExcel2003です。
よろしくお願いいたします。

Aベストアンサー

開いたブックにあるVBAコードをテキストに出力する方法
Sub VBExport(WKB As Workbook)
  Dim A, B
  Set A = WKB.VBProject.VBComponents
  For Each B In A
    B.Export "C:\~" '★テキストファイルでエクスポート
    xxxxxx '★上記テキストファイルを調べる処理
  Next
End Sub
ブックやシートにあるコードも(空でも)出力されます。
もし、標準モジュールのみ処理したい場合は「B.Type = 1」に限り
エクスポートします。

Q[ctrl] + [V] で書式無しテキストとして貼り付ける

PowerPoint2002を使用しています。

テキストを [ctrl] + [C] でコピーし、[ctrl] + [V] で貼り付けるときに、書式無しテキストとして貼り付ける方法はないでしょうか?

書式なしテキストとして貼り付けるには、
「編集」→「形式を選択して貼り付け」→「書式なしテキスト」と選択しますが、これでは手間がかかります。
マクロを登録すればよいのかもしれませんが、もっとスマートにできる方法がありましたら教えてください。

Aベストアンサー

こんにちは

私はテキストエディタを別に立ち上げておき,一度そこにペーストしてから再びコピーし
て,パワーポイントにペーストしています.
コピー&ペーストを2回繰り返すことになりますが,[型式を…]をやるよりは楽かなぁ~
と思っています.書式を無くしたいときはいつもこの方法を使っています.

[型式を…]のコマンドをツールバーに入れてしまうという方法もありますが,メニューか
ら選ぶという手間が省けるという程度です.


人気Q&Aランキング

おすすめ情報