- ベストアンサー
ACCESS SQLでの重複値の制御
- ACCESSを利用して簡易的なシステムを構築しております。複数テーブルからデータ抽出しているのですが、重複している列の表示のみを制御したいと考えています。
- 同一商品で複数回の仕入が発生するため、同じ商品CD、商品名称が複数回表示されてしまいます。見た目的に最初の1度のみ表示するよう制御したいです。
- 質問文章では、ACCESS SQLを使用して重複値の制御についての問題が説明されています。複数テーブルからデータを抽出し、同じ商品CD、商品名称が重複して表示されるため、その制御方法についての質問です。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
その他の回答 (6)
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
補足:Rename関数だけでもOK! 先の回答は応用されるのに問題があるかも・・・。 そこで、もう少し簡便なやり方を考えてみました。 Option Compare Database Public intCount As Integer Function Rename(newName As String) As String Static nowName As String Dim strReturn As String intCount = intCount + 1 If StrComp(nowName, newName, 0) <> 0 Or intCount = 2 Then nowName = newName strReturn = nowName Else strReturn = " 〃" End If Rename = strReturn End Function この関数を標準モジュールに追加します。 【クエリB】 SELECT Rename([GoodsName]) AS Hinmei, テーブル1.ID, テーブル1.GoodsName FROM テーブル1; このクエリを元に帳票フォームを作成します。 【フォームの仕掛け】 Option Compare Database Option Explicit Private Sub Form_Load() intCount = 0 End Sub このフォームは添付写真のように表示されます。 【お願い】更なる改善を! 確かに、Rename関数で目的は達成されます。が、どうにも広域変数intCountを利用している点がいただけません。できれば、この点の改善にアタックされてください。狙いは、フォームの仕掛けを不要にすること。当方、Accessから遠ざかること10数年。ここら辺りが限界です。
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
一意の列はクエリにて容易に発生させることができますよ。 Option Compare Database Public intCount As Integer Function Numbers(strFieldName As String) As Integer intCount = intCount + 1 Numbers = intCount End Function クエリ: Numbers([GoodsName]) AS ID フォーム: Option Compare Database Option Explicit Private Sub Form_Load() intCount = 0 End Sub
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
On Error GoTo Err_DBCount Dim N Dim rst As ADODB.Recordset 関数の冒頭のDim文に不要な1行が残存していました。 このように修正して下さい。
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
補足:ADO関数 Public Function DBCount(strQuerySQL AS String) As Variant On Error Goto Err_DBCount Dim N Dim strQuerySQL AS String Dim rst AS ADODB.Recordset Set rst = New ADODB.Recordset With rst .Open strQuerySQL, _ CurrentProject.Connection, _ adOpenStatic, _ adLockReadOnly If Not .BOF Then .MoveFirst N = Nz(.Fields(0), 0) End If End With Exit_DBCount: On Error Resume Next rst.Close Set rst = Nothing DBCount = N Exit Function Err_DBCount: MsgBox "SELECT 文の実行時にエラーが発生しました。(DBCount)" & Chr$(13) & Chr$(13) & _ "・Err.Description=" & Err.Description & Chr$(13) & _ "・SQL Text=" & strQuerySQL, _ vbExclamation, " 関数エラーメッセージ" Resume Exit_DBCount End Function DBSelect関数は少し大きい関数ですのでDBCount関数を紹介しておきます。DCount関数の3倍速で動作する筈です。なお、ADOの参照設定は必要です。
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
Q、フォームの表示を工夫。 A、まず、フィールド[isFirst]を追加。 加えて、品名表示用のフィールド[Hinmei]も追加。 次に、それぞれのプロパティを設定。 フォームのレコードソース=クエリAとして話を進めます。 【isFirst】 =DBSELECT("Select Count(ID) FROM クエリA WHERE ID < " & [ID] & " AND GoodsName = '" & [GoodsName] & "'")=0 【iHinmei】 =IIf([isFirst],[GoodsName]," 〃") これで、クエリA自体に細工を施す必要を無くせます。やっぱり、クエリはシンプルが一番ですので・・・。 【クエリA】 SELECT ID, GoodsName FROM テーブル1 ORDER BY ID; [isFirst] の判定は、レコードソースを[ID]順に並べ、同じ品名の登場回数をカウントしています。過去に登場してなければ、その値は0。ですから、クエリをこのような判定が可能なように用意する必要があります。 Access の関数を利用しても構いませんが、処理速度に難点があります。それを解決するには、ADOを利用した関数の利用をお勧めします。その関数は、後ほどに補足します。 添付図は、フォームの表示例です。
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
補足
回答ありがとうございます。 この方式を実現するには、一意な値(キー)が必須になりますでしょうか?。私が抽出したいデータには一意になりうる項目がなく、この方法で実現が難しいようです。