Access (一般機能)

Accessの一般機能に関するフォーラムです。
  • 掲示板への投稿には会員登録(無料)が必要です。会員登録がまだの方はこちら
  • 掲示板ご利用上のお願い」に反するご記入はご遠慮ください。
  • Q&A掲示板の使い方はこちらをご覧ください
トピックに返信
質問

 
(指定なし : 指定なし)
SQLのデータ抽出について
投稿日時: 17/10/03 23:17:30
投稿者: ビーズ

はじめまして。
   
SQLのSelect文でのデータ抽出について質問です。
   
テーブルに商品コードが入ってます。
基本的には1レコードに商品コードが1つなのですが
まれに1レコードに商品コードが複数入っているものもあり
それが/(スラッシュ)で区切られております。
このスラッシュで区切られたものを分解して
1つのレコードにすることはできますでしょうか?
   
どうしてもわからないので、
どなたかお力を貸して下さい。
   
宜しくお願いします。
   
   
【例】
  
<テーブルのデータ>
商品名 商品コード
りんご A12345/B12345/C12345
みかん B56789
バナナ C56789
なし  D12345
ぶどう E12345/A56789
   
    ↓ ↓
  
<抽出したデータ>
商品名 商品コード
りんご A12345
りんご B12345
りんご C12345
みかん B56789
バナナ C56789
なし  D12345
ぶどう E12345
ぶどう A56789

回答
投稿日時: 17/10/04 10:18:52
投稿者: sk

引用:
SQLのSelect文でのデータ抽出について質問です。
    
テーブルに商品コードが入ってます。
基本的には1レコードに商品コードが1つなのですが
まれに1レコードに商品コードが複数入っているものもあり
それが/(スラッシュ)で区切られております。
このスラッシュで区切られたものを分解して
1つのレコードにすることはできますでしょうか?

/ で区切られている[商品コード]の個数に上限があるのか否か、
もし上限があるなら具体的に何個までであるか次第かと。
(基本的には InStr 関数、Mid 関数、ユニオンクエリ等を
駆使することになるはず。それぞれの[商品コード]の文字数が
常に 6 桁で固定されているなら InStr 関数 は不要)
 
最多で何個の[商品コード]が含まれるかが特に決まっていないのであれば、
別の正規形テーブルにレコードを出力する VBA のコードを
作成なされた方が無難な気がします。

投稿日時: 17/10/04 17:02:11
投稿者: ビーズ

skさん
 
ありがとうございます。
 
関数使わないと難しいですよね…
 
もう少し頑張ってみます。

回答
投稿日時: 17/10/12 12:08:21
投稿者: mendel

以下の環境にて作成しました。
Windows7 Pro 32bit
Access2010
ファイル形式:accdb
 
基本的考え方
フィールド[商品コード]の文字列を正規表現で分割する。
分割毎に<テーブルのデータ>と同一の構造のテーブルにAddNewする。
*区切り記号は"/"や"|"や","を認めている。
*区切り記号の個数に上限はない。
*区切り記号が連続して出現することを認める。
 
[商品コード]の条件
[商品コード]の区切りは「アルファベット」と「数値」でない。
[商品コード]の1文字目はアルファベット大文字である。
[商品コード]の2文字目以降は必ず数値である。
*例:A1 ではなく A00001 である。
区切り記号は必ず[商品コード]で挟まれている。
*[商品コード]フィールド1文字目、最終文字が半角"/"でないということ。
*例:/E12345/A56789 や E12345/A56789/ や /E12345/A56789/ は存在しない。
 
正規表現"[A-Z]{1}[0-9]{5}"の意味
1文字目が半角アルファベット大文字1文字、その後5桁の半角数値が連続する。
 
上記の条件を外れる場合は、正規表現の条件を変更する必要があります。
 
以下の手順にて実行
テーブル[T_moug]を作成。
[T_moug]にフィールド[商品名]と[商品コード]を作成。
各フィールドにビーズ様が提示されたデータを入力。
テーブル[T_moug]の構造のみをコピーし、テーブル[T_mougdup]を作成
[T_moug]のフォームを単票形式で[F_mougORG]として作成。
[T_mougdup]のフォームを単票形式で[F_mougCHG]として作成。
空白のフォームを[F_mougMain]として作成。
フォーム[F_mougMain]に[F_mougORG]と[F_mougCHG]をそれぞれ配置。
フォーム[F_mougMain]にコマンドボタン[cmdsplitProductCode]を配置。
 
コネクション接続及び切断と
レコードセット生成・破棄の処理は別関数です。
 
---以下のコードを記述---
Option Compare Database
Option Explicit
 
Private Sub cmdsplitProductCode_Click()
 
Dim formORG As Form
Set formORG = Application.Forms!F_morgMain!F_mougORG.Form
formORG.Recordset.MoveFirst
Do Until formORG.Recordset.EOF
    Call regxSplit(formORG.商品名.Value, formORG.商品コード.Value)
    formORG.Recordset.MoveNext
Loop
 
Set formORG = Nothing
 
Call dispmougCHG
 
End Sub
 
Private Sub regxSplit(productName As String, productCodes As String)
 
Dim reg As Object
Set reg = CreateObject("VBScript.RegExp")
 
reg.Pattern = "[A-Z]{1}[0-9]{5}"
reg.IgnoreCase = True
reg.Global = True
 
Dim Matches As Object
Set Matches = reg.Execute(productCodes)
 
Dim Match As Object
 
For Each Match In Matches
    'Debug.Print Match.Value
    Call registRecord(productName, Match.Value)
Next Match
 
Set Matches = Nothing
 
End Sub
 
Private Sub registRecord(productName As String, productCode As String)
 
Call createRecordset("T_mougdup", adLockOptimistic)
 
adoRs.AddNew
    adoRs!商品名.Value = productName
    adoRs!商品コード.Value = productCode
adoRs.Update
 
Call destroyRecordset
 
End Sub
 
Private Sub dispmougCHG()
 
Dim formCHG As Form
Set formCHG = Application.Forms!F_morgMain!F_mougCHG.Form
formCHG.RecordSource = "T_mougdup"
formCHG.商品名.ControlSource = "商品名"
formCHG.商品コード.ControlSource = "商品コード"
Debug.Print formCHG.Recordset.RecordCount
 
Set formCHG = Nothing
 
End Sub
---ここまで---
 
以上。

トピックに返信