This is my first post on Be Communities, so if anything is wrong do not judge me very strictly.. I was browsing this great website for over a week now trying to find a solution to my problem, but still seem to be stuck on it...
I work for a company who uses Microstation V8 XM Edition to design railway signalling systems and they asked me (IT guy) to produce a macro which would enable them to save time and reduce number of mistakes.
Ok, here is my problem. I got a user interface created in VBA and i got three textboxes. User will need to input data into these boxes and then by pressing "Process" button macro shall populate particular cells in .dgn file with info from textboxes. Each cell has 5 DataEntry Regions so I need to use them.
Name of a whole cell is: UP_EDF.
The problem is that I'm a complete newbie with Microstation and cannot really workout how to do it. I do have experience working with VB.
I was able to find like a guide which one of Be Community's members posted:
1. Get Cell Element.2. Enumerate over the contents of the cell using CellElement.MoveToNextElement3. For each TextElement encountered, determine if it has DataEntryRegions and how many (TextElement.DataEntryRegionsCount). Each TextElement can have 0 or more EDFields. You will want to keep track of which EDField you want to populate. For example, if you have 2 TextElements with 2 EDFields each, then to populate EDField number 3 in the entire cell, you would want the first EDField in the second Text Element.4. Once you have the desired TextElement then you would grab a copy of it from the Cell Enumerator using CellElement.CopyCurrentElement.5. Populate the desired EDField(s) using TextElement.DataEntryRegionText(idx)=newText.6. Then you would update the TextElement in the cell by writing back with CellElement.ReplaceCurrentElement <updated TextElement>
But it is not really taking me very far...
I have also attached a picture of a cell I'm trying to update. I would really appreciate your help.
Thank you guys in advance.
The purpose of data entry fields is to make is easy for a user to put text in the right place. They are a hangover from MicroStation's predecessor IGDS.
If you are in programmatic control of the data entry, as you are with your VBA UserForm, then the data entry fields are redundant. Your VBA can do whatever it wants with the text the user enters.
So forget the data entry fields. When your user clicks OK, simply find each TextElement in the cell and replace it with the content of a TextBox on your UserForm. From your screenshot I guess that you need to find what fields the user has already completed, then look for the next blank TextElement .
Regards, Jon Summers LA Solutions
Jon, thanks for your reply.
The thing is how to identify each cell using vba? As you can see from my attached image there are 5 DataEntryRegions in each cell. Do you know if it is possible to get a unique number of each DataEntryRegion? I know there are Element IDs of each cell which includes all 5 DataEntryRegions... I need to that to be able to intelligently identify numbers in a particular DataEntryRegion in a future. You can see what I mean in a picture attached. For example if VERSION is KK5 at the moment VBA needs to scan that particular field and if KK5 is detected then program shall increment KK5 to KK6. I hope you understand what Im trying to say :)
Or is it would be possible to specify in the code something like: ElementId: 2619 = textbox1.text?
Your help is very appreciated :) Thank you very much.
andrejusk said: There are 5 DataEntryRegions in each cell
It's hard to cell from a screenshot, but it looks to me that each cell has a single enter-data field five characters long.
What we can't know from a screenshot is how that table is constructed. We don't know if it's one big cell, with gridlines to demarcate columns and rows, or if it's a stack of 3-column cells, or a 3x9 cell matrix.
andrejusk said:For example if VERSION is KK5 at the moment
Version identifies a column of cells. Find the column that contains Version and search that column for the last cell that contains a non-blank TextElement. Use the value in that cell to compute a new value that you update and use to set the TextElement in the following cell.
Here are a couple options:
1) Relative origin points. If you look at all the text elements in your chart, you should be able to compare x & y values (assuming 2d) to see which cell is which.
2) I don't know much about tags, but possibly use tags?
3) Add custom non-graphic user data to the elements. (Requires getting a number assigned to you from Bentley.)
I think you need to step back and rethink this and maybe talk to your users. If the user has to type the entry into a text field in a dialog box that you are generating then you're not really saving them any time because the information is not available to reuse. The macro would save them time if they have to do this multiple times or do the same thing in another program for another use and this information is torer somewhere else besides Microstation. A better solution in that case would be using a database or spreadsheet to input or calculate the data then using this information in multiple programs, one being Microstation. I personally never liked the linking of files to Microstation but that option is there. Jon is right about not using the data fields in this scenerio as you would be able to control all aspects of the text from your macros.
Thanks for your replies guys!
To Jon ->
Yes, you are right each cell has a single data field five characters long. I found out that each this data field has a unique number. I would like to use this unique number (ElementID) to update cells. Every single drawing has identical cells with identical ElementIds so I can hardcode unique numbers into my vba macro and do something like ElementId 1029 = "KK5-4".
The question is how to use ElementID in a code? I cannot find a way... Can someone post a sample code maybe.
Table is constructed in a way of one big cell with gridlines.
To Robert ->
I did think to use x and y coordinates this is would be relatively easy but I need to use data fields which are already in a cell. Using x and y coordinates to write text on a drawing would just overwrite text on top.
I'm not sure how tags work.. :(
To Budlite ->
I got your point but it will save our engineers some time because Im planning to use my tool on a number of drawing at once instead of entering data one by one. Also tool would convert all letters to uppercase automatically and would prevent engineer to use incorrect version number on a number. For example if current version is KK5 program will not let him to type in KK4 it will automatically populate to KK6.
andrejusk said: I found out that each this data field has a unique number
No. Data fields, as I may have mentioned before, are a legacy from an older CAD system. They are just placeholders. A data field is not an element, and does not have an ElementID.
andrejusk said:I would like to use this unique number (ElementID) to update cells
A data field is placeholder text in a a TextElement. Each and every element in a DGN file has a unique 64-bit ID. VBA calls that the ElementID property of an Element class. You can use that ID to retrieve an element:
Dim oElement As Element
Set oElement = ActiveModelReference.GetElementByID (1234)
If oElement.IsTextElement Then
.Text = "KK6"
andrejusk said:The question is how to use ElementID in code?
A problem with ElementID is that it's a 64-bit integer number. VB/VBA don't understand integers bigger than 32-bit. Bentley Systems provide the DLong data type, which you can use to encapsulate an ElementID.
andrejusk said:I'm not sure how tags work
Stick to text for the time being, although Robert's advice is sound. Think of a tag set as a database table inside a DGN file. Using the variouis tag classes, you can populate that table with real data.
andrejusk said: Tool would convert all letters to uppercase automatically and would prevent engineer to use incorrect version number on a number
You can do all that in your VBA UserForm. The TextElement is used to store the result of your validation process.
Jon this is a great help you are providing thanks a lot!!!
I have tried to use your code just to update one text element within a drawing with a text but cannot accomplish it for some reason I'm always getitng an error saying "Type mismatch"...
This is a code:
Private Sub CommandButton3_Click()
Dim id As DLong
id = "2619"
Set oElement = ActiveModelReference.GetElementByID(id)
.Text = "KK6"
What am i doing wrong?
P.S. Do you know what source I can use to learn more about VBA and Microstation? I'm currently reading MicroStation VBA book but it is not really informative in my case....
Dim id As DLong
id = "2619"
A DLong is a numeric type. You can't assign a String to a DLong any more than you can assign a String to an Integer. You should use one of the conversion function. For example:
id = DLongFromLong (1234) ' DLongFromXxx documented in MicroStation VBA help
id = DLongFromString ("2619") ' DLongFromXxx documented in MicroStation VBA help
Thank you very much for all your help and input guys. I really appreciate it!!! It helped me a lot and I learned a lot! I'm now almost in the end of finishing my project!
What a great website!!!