BlueSpruce, I don't do anything special with MVFs. I store information in lookup tables that are managed using their forms. Like with everything else in my databases, the goal is to create reports and to make verbal suggestions to users (TTS).I think you know more about Access MVF's than anyone else because you've been frequently using them ever since they made their debut in A2007. So perhaps you should write that book? Decades ago, I worked on projects involving Informix and Oracle backends that had "collections" and "arrays" respectively, and it was a real PITA. Have you learned any useful tricks when dealing with Access MVF's?
We can't override the blocking.I would think Dakota could PM an admin to see if they can override the blocking?
I think there are two big differences where MVFs are fine and where you most likely will get into problems down stream.BlueSpruce, I don't do anything special with MVFs. I store information in lookup tables that are managed using their forms. Like with everything else in my databases, the goal is to create reports and to make verbal suggestions to users (TTS).
MVFs do the first well because they display multiple attributes in columns. For example, if I want to see all the diseases that a person has then an MVF in a form will allow me to select all of their diseases for every member of a family unit, and it will show the disease names using commas or some other punctuation mark. The report would then show them in a column, so it will be easier for the user to read the information. Checkboxes make selecting one or more diseases easy for the user.
This doesn't mean that there aren't other ways to do this. I am only saying that I like using MVFs. They require no code, and they are intuitive to use for attribute information.
Also MVFs in reports expand downward automatically when directed to do so.
This works well for both my forms and reports because my tables have many fields. I optimize for space on both the monitor and on paper. Some of my tables have 10 MVFs. I place them strategically on forms and reports. Unlike most developers, I don't need to manipulate attributes in MVFs. My reports are designed to be documents, not lists of data.
To let users edit information in MVFs, I use forms for my MVFs. I label those forms as lfrm to distinguish them from main forms and subforms. This way Access groups and sorts my forms and other objects using assigned prefixes. I also give the objects similar names. So for one table, say Diseases, the table is named tblDiseases, the lookup table is named lkuDiseaseType, the main form is frmDiseases, and the form to edit the lookup table is lfrmDiseaseType, the main report is rptDiseases, and so on.
The best thing about using MVFs for me is reusing them multiple times. So the list of diseases can be used to describe a person's health, used with good foods to eat, and with bad foods to avoid. I can also use the list with foods that have been recalled by the government and producers. This is my approach to normalization, but I am not sure that that is what it is. By the time I am finished, MVFs will allow for Many-to-Many-to-Many relations.
I would think Dakota could PM an admin to see if they can override the blocking?
That's not how I use MVFs. All of mine use a visible, not a hidden, table. I call them lookup tables because the MVFs use them. Other tables, forms, and reports can also use them. Again, the big advantage, IMHO, is how the attributes look in forms and reports. I usually set the formatting in forms to System Separator, but to New Line in reports. If a user wants to change the settings, they are right there in the Property Sheet. That way, the user can have it their way and doesn't need me.I will just point out that we recommend not MVFs but Combo Boxes based on a separate lookup table. Comparing the two, the MVF has a hidden infrastructure and thus is harder to maintain, particularly if you need to add or remove entries in the underlying table. BUT... otherwise, they take up the same amount of space. If I'm going to store code 12 and "XYZ", the only difference is whether I can see the name of the definition table. There is no difference in the space used. But that one little difference - a visible name for the supporting table - allows me to more easily DO things with the underlying data.
Your comments in post #22, middle section, talk about the advantages of MVFs, NONE OF WHICH are distinct from ordinary combo-box/table behavior. (They can't be, since it is the same mechanism.) The combo box, if you build it with a wizard, does not require you to engage in coding. You can control the nature of the drop-down behavior. You can get the combo to show multiple columns. You keep on showing us a distinction based on no difference. The REAL difference is that the MVF implied table, being hidden, is harder to work with when changes are needed. And there is the perceptual difference that hides how much you use that feature. I believe that each MVF creates its own hidden table, which means that even if you have the chance to re-use a set of values, you won't - potentially leading to duplicated data when sharing via combo/table setups on the forms could easily re-use data commonly looked up, via data sharing techniques. And heavens forfend that you should ever have two MVFs representing the same thing but with different codes stored for selection for the same values in two different hidden tables.
Excellent advice!... Keep in mind the OP doesn't write VBA code, rather relies on wizards and macros to build his apps, so we try to help him within those constraints.I think there are two big differences where MVFs are fine and where you most likely will get into problems down stream.
I call it a "Simple List" or a "Complex List". You seem to be suggesting "simple lists" and thus not a big deal to go with MVF. But you really need to think about the potential limitations now. And since you do not know where this is going, you can paint yourself into a corner.
1. In the Simple List, the data you are choosing to put in your MVF comes from a table with few fields. Mostly it is just a value. This list does not hold any foreign keys to other related tables. Other tables do not have foreign keys to this list. There are no fields such as dates, currencies, or other values that you may need to do queries against. So a list of products, Disease types where you are just concerned in showing the choices. If all you are ever going to do is show these choices and query against these choices then using MVF is fine
2. In the Complex List the table you are pulling from has a lot of information to include foreign keys to other tables or other tables referencing this list. Lets assume DiseaseType has the following fields
tblDiseaseType
- DiseaseName
-DiseaseDescription
-DiseaseCategory_FK ' foreign key to disease category table
- DiseaseCricality_FK ' foreign key to criticality table
- PercentPopulationAffected ' numeric
-RiskPercentage ' numeric
and a related table
tblOrgansAffected 'references tblDiseaseType
- DiseaseTypeID_FK ' a foreign key to the disease table
- OrganID_FK ' a foreign key to the organs table
Because I am tracking that level of detail it tells me I probably want to do things like answer
- Show all family members with diseases that are high risk and all organs affected
- Show family members with a disease risk over 70%
- Count total family members with a disease in the parasitic infection category that are high criticality
The above questions are trivial in a standard design; the above questions are near impossible to answer with an MVF in the mix.
So it takes some hard thought of the downstream effects and what I will need to do with the data.
You say that your "requirements" are continually changing and do not know what functionality you will need. If I am 100% confident a simple list of choices is all the future holds then knock yourself out with MVF if you understand the other limitations. But if you think you want to do more with the data in the list table then just show and query the choices, you are better off putting the work in now. Sometimes a simple list starts to grow because you decide you want to do more with the related data.
I am with @DakotaRidge because the above is completely misleading. You cannot simply replace an MVF with a combo.I will just point out that we recommend not MVFs but Combo Boxes based on a separate lookup table. Comparing the two, the MVF has a hidden infrastructure and thus is harder to maintain, particularly if you need to add or remove entries in the underlying table. BUT... otherwise, they take up the same amount of space. If I'm going to store code 12 and "XYZ", the only difference is whether I can see the name of the definition table. There is no difference in the space used. But that one little difference - a visible name for the supporting table - allows me to more easily DO things with the underlying data.
Your comments in post #22, middle section, talk about the advantages of MVFs, NONE OF WHICH are distinct from ordinary combo-box/table behavior. (They can't be, since it is the same mechanism.) The combo box, if you build it with a wizard, does not require you to engage in coding. You can control the nature of the drop-down behavior. You can get the combo to show multiple columns. You keep on showing us a distinction based on no difference. The REAL difference is that the MVF implied table, being hidden, is harder to work with when changes are needed. And there is the perceptual difference that hides how much you use that feature. I believe that each MVF creates its own hidden table, which means that even if you have the chance to re-use a set of values, you won't - potentially leading to duplicated data when sharing via combo/table setups on the forms could easily re-use data commonly looked up, via data sharing techniques. And heavens forfend that you should ever have two MVFs representing the same thing but with different codes stored for selection for the same values in two different hidden tables
Thanks, Pete. All I want to do with MVFs is show lists of attributes. I agree that a more analytical application may need other tools. This is why my Finance and Health database already has 450 tables and forms. The forms look like the above screenshot. The forms are related to other forms and reports. Some of them use queries to answer questions that you proposed here, while others just allow the user to enter information and display it. Most of the forms aggregate data such as costs and dates. It depends.I think there are two big differences where MVFs are fine and where you most likely will get into problems down stream.
I call it a "Simple List" or a "Complex List". You seem to be suggesting "simple lists" and thus not a big deal to go with MVF. But you really need to think about the potential limitations now. And since you do not know where this is going, you can paint yourself into a corner.
1. In the Simple List, the data you are choosing to put in your MVF comes from a table with few fields. Mostly it is just a value. This list does not hold any foreign keys to other related tables. Other tables do not have foreign keys to this list. There are no fields such as dates, currencies, or other values that you may need to do queries against. So a list of products, Disease types where you are just concerned in showing the choices. If all you are ever going to do is show these choices and query against these choices then using MVF is fine
2. In the Complex List the table you are pulling from has a lot of information to include foreign keys to other tables or other tables referencing this list. Lets assume DiseaseType has the following fields
tblDiseaseType
- DiseaseName
-DiseaseDescription
-DiseaseCategory_FK ' foreign key to disease category table
- DiseaseCricality_FK ' foreign key to criticality table
- PercentPopulationAffected ' numeric
-RiskPercentage ' numeric
and a related table
tblOrgansAffected 'references tblDiseaseType
- DiseaseTypeID_FK ' a foreign key to the disease table
- OrganID_FK ' a foreign key to the organs table
Because I am tracking that level of detail it tells me I probably want to do things like answer
- Show all family members with diseases that are high risk and all organs affected
- Show family members with a disease risk over 70%
- Count total family members with a disease in the parasitic infection category that are high criticality
The above questions are trivial in a standard design; the above questions are near impossible to answer with an MVF in the mix.
So it takes some hard thought of the downstream effects and what I will need to do with the data.
You say that your "requirements" are continually changing and do not know what functionality you will need. If I am 100% confident a simple list of choices is all the future holds then knock yourself out with MVF if you understand the other limitations. But if you think you want to do more with the data in the list table then just show and query the choices, you are better off putting the work in now. Sometimes a simple list starts to grow because you decide you want to do more with the related data.
If I was going to do it for something this big, I would use the description field and mark all fieldsHow can I give them one command button that will delete all sensitive records across the entire database?
That sounds like the reason. @DakotaRidge posted several screenshots in that long thread, and only has 34+ posts to date. Attaching images to posts requires providing the URL to the images, or just drag/drop? I would think Dakota could PM an admin to see if they can override the blocking?
BlueSpruce, I suspect AW counts the number of posts that a person submits to AW and if that number is not above a certain threshold, then the system blocks new posts to a thread. I can start new threads, and I can respond to other threads. I just can't go over 100 posts until I become a member of the club.I still don't understand why @DakotaRidge cannot post anything to those two specific threads he initiated, but can post to others with images included. The 100 postings threshold has nothing to do with it
That's true Duane. Here's the text that I tried to post and it was blocked. I saved it to Word. I was responding to Pat. I made a few edits today.I don’t believe @DakotaRidge has ever stated the full contents of what is contained in the post. Was there an attachment, image, link, script,…?
Private Sub cmdDelSensitive_Click()
Dim rtn As Long
Me.txtOut = Null
rtn = MsgBox("This will delete all sensitive data from your DB. Make sure you have a backup before attempting. Do you want to continue?", vbCritical + vbYesNo, "Delete Data")
If rtn = vbYes Then
ClearSensitive
End If
End Sub
Public Sub ClearSensitive()
Dim tdf As TableDef
Dim rs As Recordset
Dim fld As Field
Dim strSql As String
Dim strOut As String
For Each tdf In CurrentDb.TableDefs
If Left(tdf.Name, 1) <> "~" And Left(tdf.Name, 4) <> "MSYS" And Left(tdf.Name, 4) <> "Copy" Then
strOut = strOut & "TABLE: " & tdf.Name & vbCrLf
Set rs = CurrentDb.OpenRecordset(tdf.Name, dbOpenDynaset)
For Each fld In rs.Fields
If DoesFieldPropertyExist(fld, "Description") Then
If Left(fld.Properties("Description"), Len("Sensitive")) = "Sensitive" Then
If fld.Required = True Then
MsgBox "Cannot clear " & fld.Name & " in " & tdf.Name & " It is required.", vbCritical
strOut = strOut & "Cannot clear " & fld.Name & " in " & tdf.Name & " It is required." & vbCrLf
Else
strOut = strOut & "-- Clearing Sensitive Field: " & fld.Name & vbCrLf
strSql = "Update " & tdf.Name & " Set " & fld.Name & " = Null"
'strOut = strOut & "----" & strSql & vbCrLf
CurrentDb.Execute strSql
End If
End If
End If
Next fld
strOut = strOut & vbCrLf
End If
Next tdf
Me.txtOut = strOut
End Sub
Function DoesFieldPropertyExist(fld As DAO.Field, propName As String) As Boolean
On Error GoTo ErrorHandler
Dim p As DAO.Property
' Attempt to access a standard property (e.g., DataUpdatable)
' This will generate an error if the property doesn't exist for this field type
Dim temp As Variant
temp = fld.Properties(propName).Value
DoesFieldPropertyExist = True
Exit Function
ErrorHandler:
' If an error occurred, it means the property was not found directly
' Now, check for user-defined properties
For Each p In fld.Properties
If p.Name = propName Then
DoesFieldPropertyExist = True
Exit Function
End If
Next p
DoesFieldPropertyExist = False ' Property not found
End Function
Thanks, Pete.The following code clears all fields in all tables in the datbase that are identified as sensitive in the description field. If the field is required it alerts you that it cannot clear it.
Code:Private Sub cmdDelSensitive_Click() Dim rtn As Long Me.txtOut = Null rtn = MsgBox("This will delete all sensitive data from your DB. Make sure you have a backup before attempting. Do you want to continue?", vbCritical + vbYesNo, "Delete Data") If rtn = vbYes Then ClearSensitive End If End Sub Public Sub ClearSensitive() Dim tdf As TableDef Dim rs As Recordset Dim fld As Field Dim strSql As String Dim strOut As String For Each tdf In CurrentDb.TableDefs If Left(tdf.Name, 1) <> "~" And Left(tdf.Name, 4) <> "MSYS" And Left(tdf.Name, 4) <> "Copy" Then strOut = strOut & "TABLE: " & tdf.Name & vbCrLf Set rs = CurrentDb.OpenRecordset(tdf.Name, dbOpenDynaset) For Each fld In rs.Fields If DoesFieldPropertyExist(fld, "Description") Then If Left(fld.Properties("Description"), Len("Sensitive")) = "Sensitive" Then If fld.Required = True Then MsgBox "Cannot clear " & fld.Name & " in " & tdf.Name & " It is required.", vbCritical strOut = strOut & "Cannot clear " & fld.Name & " in " & tdf.Name & " It is required." & vbCrLf Else strOut = strOut & "-- Clearing Sensitive Field: " & fld.Name & vbCrLf strSql = "Update " & tdf.Name & " Set " & fld.Name & " = Null" 'strOut = strOut & "----" & strSql & vbCrLf CurrentDb.Execute strSql End If End If End If Next fld strOut = strOut & vbCrLf End If Next tdf Me.txtOut = strOut End Sub Function DoesFieldPropertyExist(fld As DAO.Field, propName As String) As Boolean On Error GoTo ErrorHandler Dim p As DAO.Property ' Attempt to access a standard property (e.g., DataUpdatable) ' This will generate an error if the property doesn't exist for this field type Dim temp As Variant temp = fld.Properties(propName).Value DoesFieldPropertyExist = True Exit Function ErrorHandler: ' If an error occurred, it means the property was not found directly ' Now, check for user-defined properties For Each p In fld.Properties If p.Name = propName Then DoesFieldPropertyExist = True Exit Function End If Next p DoesFieldPropertyExist = False ' Property not found End Function
The tables starting with Copy still have data in those fields. To run this again Copy the copies and rename those so they do not start with the word copy. Or add some tables and mark certain fields sensitve.