データベースとプログラミングに関する限られた (まだゆっくりと成長している) 知識のために、かなり複雑なデータベースを構築しています。ですから、あなたの助けに本当に感謝しています。
データベースは、顧客、建物、部屋、および部屋にある機器を追跡します。
データベースのほぼ全体をクエリする、作成したユニオンクエリをフィルタリングする検索フォームがあります。SQL は次のとおりです。
SELECT tblcustomer.organizationfk,
tblcustomer.shopnamefk,
tblcustomer.officesymfk,
tblcustomer.lastname,
tblcustomer.firstname,
tblfacilitymgr.buildingfk,
tblrooms.roomspk,
tblbuilding.buildingname,
tblrooms.roomname,
tblcabinet.cabinetname,
tblequipment.cabinetfk,
tblequipment.equipmentnamefk,
tblequipment.equipmentbrandfk,
tblequipment.equipmentnetworktypefk
FROM ((tblbuilding
INNER JOIN tblrooms
ON tblbuilding.buildingpk = tblrooms.buildingfk)
INNER JOIN (tblcustomer
INNER JOIN tblfacilitymgr
ON tblcustomer.customerpk =
tblfacilitymgr.customerfk)
ON tblbuilding.buildingpk = tblfacilitymgr.buildingfk)
LEFT JOIN (tblcabinet
LEFT JOIN tblequipment
ON tblcabinet.cabinetpk = tblequipment.cabinetfk)
ON tblrooms.roomspk = tblcabinet.roomsfk
UNION
SELECT tblcustomer.organizationfk,
tblcustomer.shopnamefk,
tblcustomer.officesymfk,
tblcustomer.lastname,
tblcustomer.firstname,
tblrooms.buildingfk,
tblrooms.roomspk,
tblbuilding.buildingname,
tblrooms.roomname,
tblcabinet.cabinetname,
tblequipment.cabinetfk,
tblequipment.equipmentnamefk,
tblequipment.equipmentbrandfk,
tblequipment.equipmentnetworktypefk
FROM ((tblbuilding
INNER JOIN tblrooms
ON tblbuilding.buildingpk = tblrooms.buildingfk)
LEFT JOIN (tblcabinet
LEFT JOIN tblequipment
ON tblcabinet.cabinetpk = tblequipment.cabinetfk)
ON tblrooms.roomspk = tblcabinet.roomsfk)
INNER JOIN (tblcustomer
INNER JOIN tblroomspoc
ON tblcustomer.customerpk = tblroomspoc.customerfk)
ON tblrooms.roomspk = tblroomspoc.roomsfk;
検索フォームは次のようになります。
cmdsearch のコードは次のとおりです。
Option Compare Database
Option Explicit 'always set this It will point out errors with field/vaiable names
Private Sub cboSearchLastName_AfterUpdate()
Me.cboSearchFirstName.Requery
End Sub
Private Sub cboSearchOrganization_AfterUpdate()
Me.cboSearchShopName.Requery
End Sub
Private Sub cboSearchShopName_AfterUpdate()
Me.cboSearchOfficeSym.Requery
End Sub
Private Sub cmdReset_Click()
Me.cboSearchBuildingName = ""
Me.cboSearchRoomName = ""
Me.cboSearchOrganization = ""
Me.cboSearchShopName = ""
Me.cboSearchOfficeSym = ""
Me.cboSearchLastName = ""
Me.cboSearchFirstName = ""
Me.FilterOn = False
End Sub
Private Sub txtBuildingID_AfterUpdate()
Me.lstFacilityMgr.Requery
End Sub
Private Sub txtRoomsID_AfterUpdate()
Me.lstRoomsPOC.Requery
End Sub
Private Sub cmdSearch_Click()
Dim strWhere As String
Dim lngLen As Long
Dim startStr As String
If Not IsNullOrEmpty(Me.cboSearchLastName) Then
startStr = IIf(strWhere = "", "", " AND ")
strWhere = strWhere & startStr & "[LastName] ='" & Me.cboSearchLastName & "'"
End If
If Not IsNullOrEmpty(Me.cboSearchFirstName) Then
startStr = IIf(strWhere = "", "", " AND ")
strWhere = strWhere & startStr & "[FirstName] ='" & Me.cboSearchFirstName & "'"
End If
If Not IsNullOrEmpty(Me.cboSearchOrganization) Then
startStr = IIf(strWhere = "", "", " AND ")
strWhere = strWhere & startStr & "[OrganizationFK] =" & Me.cboSearchOrganization
End If
If Not IsNullOrEmpty(Me.cboSearchShopName) Then
startStr = IIf(strWhere = "", "", " AND ")
strWhere = strWhere & startStr & "[ShopNameFK] =" & Me.cboSearchShopName
End If
If Not IsNullOrEmpty(Me.cboSearchOfficeSym) Then
startStr = IIf(strWhere = "", "", " AND ")
strWhere = strWhere & startStr & "[OfficeSymFK] =" & Me.cboSearchOfficeSym
End If
If Not IsNullOrEmpty(Me.cboSearchBuildingName) Then
startStr = IIf(strWhere = "", "", " AND ")
strWhere = strWhere & startStr & "[BuildingFK] =" & Me.cboSearchBuildingName
End If
If Not IsNullOrEmpty(Me.cboSearchRoomName) Then
startStr = IIf(strWhere = "", "", " AND ")
strWhere = strWhere & startStr & "[RoomsPK] =" & Me.cboSearchRoomName
End If
If Not IsNullOrEmpty(Me.cboSearchEquipmentName) Then
startStr = IIf(strWhere = "", "", " AND ")
strWhere = strWhere & startStr & "[EquipmentNameFK] =" & Me.cboSearchEquipmentName
End If
If Not IsNullOrEmpty(Me.cboSearchEquipmentSerialNo) Then
startStr = IIf(strWhere = "", "", " AND ")
strWhere = strWhere & startStr & "[SerialNoFK] =" & Me.cboSearchEquipmentSerialNo
End If
Call MsgBox(strWhere, vbOKOnly, "Debug")
lngLen = Len(strWhere) - 5
If lngLen <= 0 Then
MsgBox "No criteria", vbInformation, "Nothing to do."
Else
'strWhere = Left$(strWhere, lngLen)
MsgBox strWhere
If DCount("*", "qryRecordSet", strWhere) = 0 Then
MsgBox "No corresponding records to your search criteria." & vbCrLf & vbCrLf
Me.FilterOn = False
Me.cboSearchBuildingName = ""
Me.cboSearchRoomName = ""
Me.cboSearchOrganization = ""
Me.cboSearchShopName = ""
Me.cboSearchOfficeSym = ""
Me.cboSearchLastName = ""
Me.cboSearchFirstName = ""
Else
Me.Filter = strWhere
Me.FilterOn = True
End If
End If
End Sub
Function IsNullOrEmpty(val As Variant) As Boolean
'First conditional validates for Nothing
'Second condition validates for an Empty String situation "" or " "
Dim ret As Boolean: ret = False
If IsMissing(val) Then
ret = True
ElseIf (val Is Nothing) Then
ret = True
ElseIf (val & vbNullString = vbNullString) Then
ret = True
ElseIf (Len(Trim(val)) <= 0) Then
ret = True
End If
IsNullOrEmpty = ret
End Function
私の検索フォームは完璧に機能します。私が抱えている問題は、一部の検索で重複した結果が返されることです。これは、ユニオン クエリに重複した結果が含まれているためです。必要なすべての情報を含むクエリを作成し、結果が重複しないようにする方法がわかりません。1 人の顧客が複数の建物の施設管理者になることができるため、1 つの建物に複数の施設管理者がいる可能性があります。1 人の顧客が複数の部屋の連絡先になることがあり、1 つの部屋が複数の POC を持つことができます。機器は 1 つの部屋にのみ配置できます。
明確にするために、建物 "A" の部屋 "1100" に 3 つの POC がある場合、建物 A の部屋 1100 を検索すると、3 つの結果が表示されます。1 つの結果だけを表示する必要があります。
フォームに 2 つのテキスト ボックスがあります (非表示になっているため、ユーザーには表示されません)。txtBuildingID および txtRoomsID。フォームの他のすべては、これら 2 つのテキスト ボックスに基づいて再クエリします。これら 2 つのテキスト ボックスの組み合わせを一意にする必要があります。これは、建物「A」のみを検索し、建物 A に 3 つの部屋がある場合、建物 ID 1 / 部屋 ID 1... 建物 ID 1 / 部屋 ID 2 などと表示されるはずだからです。
理由は、複数の基準でフィルタリングしたいのですが、一意の建物 ID / 部屋 ID のみを表示するためです。これは、"Smith" を検索し、彼が建物 A、部屋 1100 の POC である場合、その建物/部屋とその部屋に関するすべての情報を表示したいからです。もしスミスが彼の電話に出なかったら、私は「ジョーンズ」に電話できるからです。
2 つのテキスト ボックスの間に一意のレコードがある限り、どのレコードが削除されてもかまいません。私は SQL について十分に知りませんが、私が知っている限りでは、SQL でこれを行うことはできないと思います。おそらく DCount を使用してレコードをカウントし、重複を削除する必要があると思います。これを行う方法がわかりません。私はグーグルで何日も過ごしましたが、解決策に近づいていません。せいぜい、構文が正しくなれば、重複の数 (Buildingfk と roomspk の間に複数の一意のレコード) を数えることができますが、重複を削除する方法がわかりません。または、削除する複製を指定する必要がある場合。個人的には、それらが削除される限り、私は気にしません。
プログラミングがとても得意な友人に尋ねたところ、彼は困惑しました。彼は私がここで尋ねるように勧めました。ですから、ここであなたの助けに本当に感謝しています。 クエリ