I've successfully developed a good portion of a project i'm working on. To add greater functionality and ease coding I'd like to have a "reference list" of properties to bridge the gap between the UI and code. A lot of the code will end up looking like:
object.property(SuperLongStringWhichActsAs.Integer.AndIsUnusableInUI)
or
object.property(integer)
So the integer relating to the "width" property might be 1, with a possible substitute value of "bunchoftext.efields.width", and I'd like to show it in the UI as "Width". If the user selects "Width" in the UI, I'd like the returned value to be "1" for use in code, as "object.property(Width)" will not work, but "object.property(1)" will.
Is there any way to store a list of strings and their related values to be referenced by the program?
Thanks in advance for any help!
Related
I've just assumed responsibility for a database written ages ago in MS Access and I need to make some changes but unfortunately, even though I used to be a very experienced Access developer some time ago, I haven't really used it to an advanced level for about 15 years and I just can't work out how to do what I need.
Specifically, I have a main form called frmOrders.
On that form I have a subform called frmJobCard.
But frmJobCard is itself a form with a subform called frmSFJCOrders.
So, when someone clicks a particular button on frmOrders, I need to be able to read the value of a textbox on frmSFJCOrders and take action based on that value.
I've so far read through dozens of posts (both on StackOverflow and other techy sources) all of which touch upon different aspects of reading from controls on subforms and I've spent over a day trying to get this right but it never actually works so I'd be grateful if someone could tell me how I just read this value.
I think I need something along the lines of...
If Forms.frmOrders.frmJobCard.Form.frmSFJCOrders.[Estimate QTY] = 0 Then
...but I just can't make it work.
I would expect the code above to evaluate to 0 then take the actions below but it just always fails on the evaluation with
Run-time error '2465':
Application-defined or object-defined error
Any help is greatly appreciated - thanks in advance :)
It should be close to this:
If Me!frmJobCard.Form!frmSFJCOrders.Form![Estimate QTY].Value = 0 Then
Note that frmJobCard and frmSFJCOrders must be names of the subform controls which may differ from the names of the forms.
Consider this Access MVPs resource which I bookmarked in my early Access programming days. Specifically you need ! to delineate within objects and . to delineate between parent/child objects with Form. qualifier for every form object.
If Forms!frmOrders!frmJobCard.Form!frmSFJCOrders![Estimate QTY] = 0 Then
Alternatively, use a functional version:
If Forms("frmOrders").Controls("frmJobCard") _
.Controls("frmSFJCOrders") _
.Controls("[Estimate QTY]") = 0 Then
I have an unbound textbox to accept the delete older than: number of days. It is in the report header. I set it to 30 days but I want the user to be able to change it. I was banging my head trying to figure out why entering 40 was not being accepted and it reverted back to 30 every time. I finally decided on using the lost_focus event to set .value to .text. That worked.
Further research showed that when the textbox get's focus text and value are both the same, 30 in my case. Changing the number in the text box to 40 shows the values of text at 40 and value at 30. Unless I specifically set Value to the value of text Access changes text to the value of value. This is different behavior than other places in Access such as forms.
Can anyone tell me why this might be? I can't find any setting that might do this. Is it because it's in a report header? what is the difference between this and every other text box I've ever used?
From a "best practices" viewpoint, Access Reports are not intended to be used interactively despite the ability to manipulate some unbound controls. Although workarounds can be implemented that function sufficiently well, such solutions are often incomplete and buggy and function differently depending on the active view: Report View vs. Print Preview. Appropriate design patterns include using Access Forms for specifying report options which then open the Report in a static configuration.
This may not satisfy the question "Why?" if seeking a deeper answer as to why Microsoft implemented inconsistent binding behavior in Access, or why they allowed interactive controls in reports at all if they don't behave the same way as in forms. But Access has plenty of other quirky behaviors that have no known/published explanation.
Regarding the priority of the Value property updating the Text property (and not vice versa): Value is the key field because it contains the actual data for the control (bound or unbound). Although it is natural to have a single control for both display and input (uh, that's how almost all controls work), the processes of displaying data and parsing user input are two distinct functions. The visual representation returned by the Text property can be manipulated using the various formatting properties, and technically could display an incomplete representation of the underlying Value data. If there are any conflicts between the stored Value property and the Text property, it is natural that the existing Value property has precedent.
My guess is that the automatic binding behavior was "relaxed" for reports to allow more flexible custom reporting output. First consider an Access Form in Datasheet view: An unbound Form control shows the same value for all records. Even if the control is edited while on a particular row, the updated value is displayed for all rows. The same control object is essentially repainted for each row and there is no concept of individual instances of the control that can hold different values. Bound controls have built-in code that repaint the control with data from the particular row, but there are still not multiple instances each "holding" the individual values. The visual output differs from an intuitive object-oriented paradigm where our minds what to assign each visual row its own in-memory instance of the controls--it just doesn't work like that in Access.
Unlike the Form behavior just described, the Report's Print Preview (and actual printed output) allows unbound controls to display different data per row using the Detail_Format() event. Within the Detail_Format() event, one can set the Value property of a control at which time the Text property is automatically updated according to various formatting properties. This update Text is then output for the current row. Perhaps (just guessing) that this behavior would not function properly if the Text property updated the value property. I suspect it would cause recursive events during report generation. Because reports are not meant to be interactive, relevant text-input parsing code was "disconnected" so that it doesn't behave like on a form.
All that explanation doesn't make Access any less frustrating nor remove its limitations, but at least learn to adapt and design things in the "Access-esque" way rather than fighting it.
your best bet is to design a form with the unbound combo boxes and have your data displayed in a subreport. I like to design my reports so that when values are updated the query for the recordsource of the report is generated doing this requires 2 queries to exist, one with all data possible and a filtered one as subreport recordsource. This will control the data for printing and also allow users to close or navigate away from the report and return to the data later.
Private Sub ComboBox1_AfterUpdate()
Dim Query1 as Object
Dim Temp_Name as Variant
Temp_Name = SubReport.SourceObject
SubReport.SourceObject = Empty
Set Query1 = Me.Form.Application.DBEngine.Workspaces(0).Databases(0).QueryDefs ("SubReport_Query")
Query1.SQL = "Select * Unfiltered_Query WHERE Field1 <= " ComboBox1 & ";"
SubReport.SourceObject = Temp_Name
End Sub
I have zero knowledge of coding. Can someone please help me with code.
My situation is as follows:
Dashboard has a Multi select List Box (Document Property). I am using that to restrict the data and calculations.
User does not want to select values each time. He wants a button where in (s)he click it once and all the values present in the list box gets selected.
Can someone please help me.
Regards,
Subro
This is fairly easy to do. Let us say that the Document Property that the list box is used for is named "Test" and it is of type "String List". Then you can use an IronPython script like so:
Document.Properties["Test"] = ["First Choice","Second Choice","Third Choice"]
Where the string list you see above, are all the values in your list box. Make sure that the strings you assign to the document property are the ones you want to populate your list with, since sometimes the displayed values can be different than the ones assigned to the document property(The case of using the "Fixed Values" option when setting up the control).
Hope that this helps.
Zenios
I inherited a fairly large project at work that is undocumented and written in VB (originally started pre .NET, ended around .NET 2). I'm in the process of updating / refreshing a lot of the code, but have run into an annoying issue that I haven't found the solution for yet. This system utilizes a UI, a Web Service, and a SQL DB.
Problem: I have a Databound Combobox (originally set to DropDownList - I'm changing it to DropDown, which is what started this mess - going back isn't an option) that is tied to a DataSet that comes from a Web Service. When a user types in the item they want manually, the data from the text field doesn't seem to associate itself with the DisplayMember, which forces the WS/SQL query to fail (it is sent a blank value when it's expecting a ValueMember). If the user types in a partial selection and then chooses the value they want from the DisplayMember list using the arrow keys or tab, the query goes off without a problem.
My Question: How do I get the text field to translate to the DisplayMember which will then properly tie itself to the ValueMember which will then allow the query to execute correctly? Sorry for making this sound complicated or convoluted; I'm sure the answer is easy and I'm just glazing over it.
The relevant bit of code is:
With cmbDID
If dtsLU.Tables.Contains(reqTable) = True Then
.DataSource = dtsLU.Tables(reqTable)
.DisplayMember = "zip"
.ValueMember = "gridID"
End If
End With
cmbDID.DataBindings.Clear()
cmbDID.DataBindings.Add("SelectedValue", dtsData, strDT & ".gridID")
I've tried changing "SelectedValue" to "Text", which almost works - but it directly translates to gridID and skips zip which ends up with an incorrect Web Service response since the zip and gridID field values are not synced (zip (DisplayMember) may be 5123 while gridID (ValueMember) may be 6047). I've tried changing "SelectedValue" to "SelectedIndex", and that got me no where.
Any help is greatly appreciated.
EDIT
To add some clarification to the process, the below pseudo code / description is roughly what happens. I could post the whole module, but I feel that would just muddy the whole question even more.
Private Sub A
FormAlpha is created with 1 ComboBox in the form of a DropDown
This DropDown is populated with a DataSet
DataBinding with a blank DataSet is added to the control to keep track of the users input
End Sub
lblSubmit_Click event is triggered on FormAlpha by the user after they have populated the DropDown with their data. lblSubmit_Click calls Private Sub Submit
Private Sub Submit
BindingContext(DropDown DataSet, tableName).EndCurrentEdit() is called
DataSet.HasChanges() is processed
If changes are present, changes are processed
HERE lies the problem
If the user has manually typed in the DropDown field, but not hit an arrow key or tab, then the DataSet registers a change, but returns a null value in all fields - it knows something was entered, but that data apparently didn't pass through the DataSet for the ComboBox (ListItems or SelectedIndex didn't change / fire I'm guessing). If the user selects the item with the arrow keys, the DataSet has the proper input (I'm assuming the Data was validated by the control at this point).
If the processed data is good, a value is entered into the database
If the processed data is bad (empty), an error is returned
End Sub
If the above can't be solved with what I've provided, but someone still knows a better way to handle this type of situation, I'm all ears. Rewriting the module isn't ideal, but fixing this problem is a necessity.
Alright, while this fix may not be ideal, it is a fix none the less.
The bare bones problem was that the text value of the DropDown wasn't causing the data to actually affect the SelectedIndex / SelectedValue of the control unless you interacted with it using the arrow keys or a mouse click. So, while the DropDown would read "1234", in reality the control saw "".
The fix I have in place for this is simply calling comboBox.text = comboBox.text whenever the user hits the submit button.
I want to pass the parameter values to Revit family.I have spend many hours on google. In result i got few links which tells Read and Write Parameter Values with VB.NET
Read and Write Parameter Values with VB.NET
in this example we are fetching parameters and writing a value in text file called ParametersValue.txt. But i am confused, how should i pass this file to Revit?
I'm hoping someone can steer me in the right direction. I would really appreciate it!
One of the first things I would do after downloading the SDK mentioned in the previous post, is install the included revit lookup addin. This has been incredibly valuable in figuring what elements are called in the API, as well as determining which storage type the parameter is using. If all of the parameters you want to update are strings, those will be fairly straightforward to set from your text file. However, if,for example, the parameter value that you think is a string is actually set by an elementid, then there will be some coding involved to get the proper info to set the parameter value.
You can easily pass parameters to component families using "FamilyManager" class. The FamilyManager class provides access to family types and parameters. Just get the parameter and set its value. As we are working in family editor for component families, we have to load the parameter values in the project. I have tried this on Revit 2019. You have to
Open family in family editor
Activate the plugin
Click on Load into Project button on addins ribbon.
Then check the parameter value in the properties of that family.
Public Sub SetParamtersForComponentFamilies(ByVal doc As Document, ByVal parameterValue As String)
Dim f As Family = doc.OwnerFamily
Using trans As Transaction = New Transaction(doc, "Creating transaction for parameters")
trans.Start()
Dim familyMgr As FamilyManager = doc.FamilyManager
Dim n As Integer = familyMgr.Parameters.Size
Dim comment As FamilyParameter = familyMgr.get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_COMMENTS)
familyMgr.Set(comment, parameterValue)
TaskDialog.Show("Paramters", "TypeComments : Updated")
trans.Commit()
End Using
End Sub
I use C# when writing Revit API code because that's what all the samples are written in, but I might be able to get you pointed in the right direction with some additional details. Are you looking to assign a value to a specific parameter? For example: Height=30"?
If so you first have to "get" the parameter. In the example in spidernet he goes through every parameter of a selected element:
Dim element As Autodesk.Revit.DB.Element = SelElement(cmdData.Application.ActiveUIDocument.Selection).Element 'Prompts you to select an element
For Each p As Parameter In element.Parameters 'Goes through every parameter in "element" and assigns the parameter to "p"
If p.Definition.Name = "Height" Then 'Check if "p" is the name you want, "Height"
p.Set(2.5) 'Because Revit knows FEET, so in order to type in 30in you use 2.5
End If
Next 'Loop through parameters
If you're looking for it to do something else, please post again.
Also, not sure you're aware, but a blog that is FULL is great Revit API info is Jeremy Tammik's: http://thebuildingcoder.typepad.com. A lot of his examples are C#, which is why I started learning C# instead of VB.NET.
If you don't have it already, make sure you get the SDK for Revit 2014 here: http://images.autodesk.com/adsk/files/Revit2014SDK_RTM0.exe
It has a TON of samples that might help too. Good Luck!