How to ask user to snap on a vertex of a line element (in the ILocateCommandEvents_Accept handler) of Microstation VBA - vba

I know how to write a VBA macro in Microstation that will ask the user to select an element:
Sub Create2DCrossLines()
' Set error handler
On Error GoTo ErrorHandler
' Let the user select the bank elements himself
Call CommandState.StartLocate(New clsSelectBanksLCE)
Exit Sub
ErrorHandler:
Call ReportError("Create2dCrossLines")
End Sub
clsSelectBanksLCE uses ILocateCommandEvents for managing that part of the logic. So the user can select a LineElement for example and when the Accept event is fired it runs an action:
Private Sub ILocateCommandEvents_Accept(ByVal Element As Element, _
Point As Point3d, _
ByVal View As View)
In my particular case we track selecting element 1 and then element 2 and once both elements are selected it proceeds. This is all fine.
My problem is this: after I accept the first element, and before proceeding to select the next (ie: in the Accept handler) I want to get the user to snap on to two vertices of the line element.
I need to know which part of the line element they want to process. I can't work out how to do this. In AutoCAD you can use GetPoint.
So I want to ask them to snap on to the first vertex on this line element, then snap onto the end vertex. After this can we move on to select the second element.
Update
I have just stumbled over this article. I notice it says:
Once the user has accepted an element, we should start another class that implements IPrimitiveCommandEvents to obtain a target datapoint. Finally, compute the offset from the supplied locate datapoint to the target datapoint and move the element.
It seems what I want but I just am not clear on the right order. At the moment I have:
ILocateCommandEvents_Start This begins the location process.
ILocateCommandEvents_LocateFilter. If the element is a LineElement, then it
assigns m_Element1 and the second event fired assigns m_Element2.
ILocateCommandEvents_Accept If both the variables are not nothing it runs the main process.
See my dilemma? It sounds like I need to:
Run one instance of ILocateCommandEvents to select one element only.
Then run one instance of IPrimitiveCommandEvents to get the first snap point.
Then run another instance of IPrimitiveCommandEvents to get the second snap point.
Then run another instance of ILocateCommandEvents to get the second element.
Finally, once the second element is accepted, perform my processing.
That is how I understand I need to do it. Or, can I use my one ILocateCommandEvents class that currently gets the user to choose two elements?
Guidance appreciated.
Update
I got it to work by following the above logic. That article really helped. The only issue I have now is that I need to draw a rubber band. But that is a separate question.

As mentioned in this article:
Once the user has accepted an element, we should start another class that implements IPrimitiveCommandEvents to obtain a target datapoint. Finally, compute the offset from the supplied locate datapoint to the target datapoint and move the element.
The link also provides example code on how to use the IPrimitiveCommandEvents event class.

Related

Conditional parallelism on LabVIEW

I am writing an application to update the numeric value given user's input value and depending on the user's input value the program checks if it is greater than 10 if it is greater than 10 then the program waits for 1 second and then will have a popup message says "true".
My intention was to call the conditional check, printing true every one second if the user's input value is greater than 10; in other words, the case structure was to be called regardless of the event structure in the same loop infinitely.
But it doesn't seem to work the way I expected. Unless there is user's new input value, getting into the event structure, the program doesn't get to the case structure even though the case structure is in a loop.
Is there any way to call the case structure not dependent to the event structure but I want to use a shift register for the numerical value and also having an event structure and a case structure in parallel.
Thanks.
You've created an Event Structure that handles the Value Change input for your numeric control, so that will do exactly what it says: wait for a Value Change event to happen. When that event is received, the code in its Event Structure frame will execute and then the Event Structure will exit.
It looks as if you've wired a value from the shift register to the timeout terminal of the Event Structure, so I assume you must also have created a Timeout event case? If so, the event structure should stop waiting after the number of milliseconds wired to the timeout terminal.
The value you check in order to decide whether to show your true message is the value that was passed in to the shift register on the previous loop iteration. If the control value changes, that comes from the NewVal terminal in the Value Changed event case. But where does it come from in the timeout case? It looks to me as if you haven't wired it in that case, because the terminal coming out of the event structure has a little dot in it instead of being solid orange. That means you will get a default value for any case where the terminal wasn't wired. The default value for numerics is zero. So if the event structure times out, the value going in to the shift register is zero, you get zero out of the shift register on the next iteration, zero is not greater than 10, so you don't see the message again.
I don't understand what you're trying to do in the event case where you've wired the NewVal terminal to a Value property node of the same control. Can you explain what that is supposed to achieve?
Your question reads as if this is a programming exercise where you have to use these specific LabVIEW structures, so rather than suggest better ways of achieving what you say you want this code to do, I'll leave it to you to decide how to change it. In the meantime though I do recommend re-reading the Event Structure help and the caveats and recommendations it links to.

Get shape control name from access form to pass value in vba

I have a form in Access with over 500 shapes that each represent a specific record. Each shape has the control name of Box1, Box2 etc. In VBA I am trying to capture the shape name so if the user clicks the shape called Box502 for example it will go to record 502. Since it is a shape, the other methods I have used are not capturing this control name. If I can capture the name, I can remove “Box” from it and get the number to use to go to that record.
If I use a command button instead of a shape I can use the code below and get it to do what I want, but there is also code that changes the color of the shape so that does not work on the command button.
Private Sub Box2_Click()
Dim strActiveCtl As String
strActiveCtl = Replace(Me.ActiveControl.Name, "Box", "")
DoCmd.GoToRecord acDataForm, "Form1", acGoTo, [strActiveCtl]
End Sub
If I use this line of code on the shape, it is grabbing another control and not what I had clicked on.
On click I was using the code builder and this line of code, but it is capturing another control and not what I am clicking on.
Dim strActiveCtl As String
strActiveCtl = Screen.ActiveControl.Name
The reason there are these little boxes are because they basically relate to a service that is monitored. There are about 550 services monitored. When the service has been noted as reviewed the shape goes from red to green. The team wanted to be able to just click on the shape as well and have it take to them to the service it was associated with.
I can't for the life of me envision a Form with over 500 shape boxes that each represent a different record. Egads.
But maybe you have a unique reason for doing this. So I won't question this design philosophy other than to say most people use "sub-forms" and "list boxes" when trying to identify individual records like you are doing. You may be able to save yourself lots of headaches by reading up on how to design forms using those methods. (As well as many other methods that avoid putting over 500 shape boxes on your form.)
However, if this is a design that you have to adhere to... there are a few things you need to know about Access and the way it resolves the active control as well as what happens when a control is clicked on.
Whenever you click on a control or shape, if you have the control properties set so it can accept "Focus", Access instantly makes that the "active control".
So if you then go to click on something else... your shape will lose it's status of being the "active control" and the new thing will now be the new "active control".
So there is no way to click on a shape and then click on something else to launch your code that you want to have performed on the previous "active control". Access doesn't keep a memory of past "active controls".
So this brings up the question of: "What can you do to figure out if a control or shape was clicked on?"
Luckily (or unluckily) for you, when a shape is clicked on, it checks if code has been written for it's "On Click" property.
Each and every shape you put on the Form will have it's very own "On Click" property. Which means you can write a function that you can place in every single shape you create. You can pass to that function the number of which "Box" it was that called it.
This is obviously very cumbersome. (Which is why I'd suggest using "sub-forms" or "list boxes".) But it's the only way you are going to capture the Box number that is different for each of the 500 boxes since there is no way to launch other code without losing the "Focus" on which box you were on.
So if you want to continue with your "500 shapes on one Form each addressing a different record"... you could write a VBA function that calls your record with an input parameter that tells what "Box" called it. Like this:
Private Sub subGoToNewRecord(intActiveCtl As Integer)
DoCmd.GoToRecord acDataForm, "Form1", acGoTo, intActiveCtl
End Sub
Then for each Shape Box you can write:
Private Sub Box1_Click()
subGoToNewRecord 1
End Sub
Private Sub Box2_Click()
subGoToNewRecord 2
End Sub
.
.
.
Private Sub Box502_Click()
subGoToNewRecord 502
End Sub
This will get you what you want. (Although, some shapes require you to click on the outline of the shape in order make it the "active control". So you may need to make your shape boundary thick and tell users to click on the boundary line.)
Once again, I have no idea why you'd want to do this. I'd suggest again to look into what "sub-forms" are and to look into what "List Boxes" are. They are much better suited to helping you select a desired record and then make that the "Active Record".
Hope that helps. :)

QTP - Clicking on a button with a given value

I've started using QTP last weekend so I'm still a bit confused about some things.
I've coded a function that opens an URL on IE, performs some actions and writes a report. But I have a little problem: at a certain point the function has to click on a button to go on but this button's value is changed at every refresh of the page.
For example: at the first access the button's value (or label) is "Results List (51)" but, if I refresh the page, the value becomes "Results List (11)".
What changes is the number inside the brackets (that identifies the number of results inside the list).
Obviously I recorded the action only one time and the result is this:
Browser("myBrowser").Page("myPage").Frame("myFrame").WebButton("Results List 51)").Click
How can I click on the button without having to worry about it's value?
You should open the object repository and have a look at the description that was create for your WebButton then make the property in question a regular expression.
In your case the value should be Results List \(\d+\), this means Result List followed by open-parentheses, followd by one or more digits (a number) followed by close-parentheses.
Here's an explanation on how to use regular expressions in UFT.
This question reminded me of the days when I was a beginner in QTP ;) I think I still am!
Coming to your question -
If you don't really care about what is inside the brackets then you can just give Results List*.* but if you want to check if there is a bracket and digits within it then use the value suggested by Motti i.e. Results List (\d+)
Detailed Steps as you are a rookie:
1) Go to Resources->Object Repository
OR
In the Resources pane expand your action and double-Click the local object repository (You recorded hence the objects will be in local)
2) Click on the Concerned Object so that the object properties specific to this object is displayed.
3) Select the property (name?), at the extreme right you will see a button to configure the value, click on it.
4) Type the text Results List (\d+) or Results List*.*, select the checkbox for regular expressions.
5) A message box will appear, Click on No and then OK button.
Your script should run now!

How to assign an output to a label in a second form through the first form?

I wanna show the output of the calculations in a second form but I am writing the code in the first form. How can I do it?
Use the parent form name in front of the control that you are trying to work with. You may need to set the modifier to Friend.
Say that the label exists in form2 and you have code in form1 that is needing to change it. So you would do it like this: form2.label.text = "the string value here"
However, keep in mind that if the control was created or is owned by a different thread then the one that is trying to edit the control, you will receive a runtime exception.
To resolve that you will need to create a delegate for the calling sub or function.

Can I find out if an AppleScript object has a certain property?

I'm attempting to script BBEdit to make me feel more at home in coming from TextMate. One thing I need to be able to do is see if an object I have a reference to has a particular property.
For instance:
tell application "BBEdit"
tell front window
get selected items
end tell
end tell
This will succeed on a project window, but not on a disk browser window, because the latter does not have a 'selected items' property. How do I see if there is such a property in the object?
Please note: I know how to inspect an object in Script Editor (get properties) to see what properties it has, but I need to know at runtime what they are.
What about the class?
tell application "BBEdit"
if class of window 1 is disk browser window then
# ...
else
# ...
end if
end tell
I don't have bbedit so I can't check, but if different types of windows exist, and each type of window has different properties, then can't you just check the window type first? Then you would know what type of properties you can get. There must be some basic property of a window that tells you its type or kind or whatever that would help you make the decision.
The only solution I have so far is to wrap it in an error handler:
try
set sel to selected items
on error errMsg number errNum
if errNum is -1700 then
-- Code that handles no selected items attribute
return
end
error errMsg number errNum
end try
-- Code that handles when selected items attribute exists
There is a difference between documents and windows in BBEdit. Windows are an element of documents, but only windows have the selection property, so you can check the type of window first and avoid catching errors entirely (and make for cleaner code as a result).
Also, try using the selection property, which is hard property in BBEdit as opposed to "selected items" because selection will always return a usable object, even if only an insertion point.