Hi you all,
I'm trying to learn a bit of programming in microstation, but I can't seem to figure this out:
I'm reworking a class I use to place cells in a drawing. Basicly the class gets a cell number from a userform, and looks up the cell, and it's "hanging" on the mousepointer. Then after a click the cell is placed in the spot in the drawing.
But now I'm rewriting the code to place multiple cells next to each other, and I have the code working to the point that when I provide the clicks manualy, a cell gets placed, the next one moves a to the left, and when I click again at the right time in the vba the next one gets placed. I've been searching the web for days now but I can't get a working solution. The code is inserted below, the sub "LeftMouseClick()" just isn't working . the out commented lines are all thing I already tried
.
Option Explicit Dim CellName As String Public Breedte As Integer Implements IPrimitiveCommandEvents Public Sub SetCellName(Cell As String) CellName = Cell End Sub Private Sub IPrimitiveCommandEvents_Cleanup() End Sub Private Sub IPrimitiveCommandEvents_DataPoint(point As Point3d, ByVal View As View) Dim atPoint As Point3d atPoint.x = point.x + Breedte atPoint.y = point.y 'draw the cell Dim oCellEl As CellElement Set oCellEl = CreateCellElement3(CellName, atPoint, True) ActiveModelReference.AddElement oCellEl oCellEl.Redraw End Sub Private Sub IPrimitiveCommandEvents_Dynamics(point As Point3d, ByVal View As View, ByVal DrawMode As MsdDrawingMode) 'method called to show dynamics Dim atPoint As Point3d atPoint.x = point.x + Breedte atPoint.y = point.y ' display a temporary cell Dim oCellEl As CellElement Set oCellEl = CreateCellElement3(CellName, atPoint, True) oCellEl.Redraw DrawMode End Sub Private Sub IPrimitiveCommandEvents_Keyin(ByVal KeyIn As String) End Sub Private Sub IPrimitiveCommandEvents_Reset() ' method called when the reset event occurs CommandState.StartDefaultCommand frmEltakoComp.Show End Sub Private Sub IPrimitiveCommandEvents_Start() 'method called at the start of the command 'Dim point As Point3d Dim c As Integer c = 0 ShowCommand "Place Cell" CommandState.EnableAccuSnap CommandState.StartDynamics frmEltakoComp.Hide LeftMouseClick End Sub Private Sub LeftMouseClick() 'Public Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long) 'Dim inputQueue As CadInputQueue 'Dim pointx As Point3d ' Set inputQueue = CadInputQueue ' Set inputMessage = inputQueue.GetInput(msdCadInputTypeDataPoint, msdCadInputTypeAny) ' Do ' Select Case inputMessage.InputType ' Case msdCadInputTypeDataPoint ' Case msdCadInputTypeReset ' Exit Sub ' End Select ' Loop 'CadInputQueue.SendCommand LeftMouseClick True CadInputQueue.SendDataPoint Point3dZero ' End Sub 'Public Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long) ' ' Public Const MOUSEEVENTF_LEFTDOWN = &H2 ' Public Const MOUSEEVENTF_LEFTUP = &H4 ' End Sub ' ' 'Public Sub LeftClick() ' ' ' ' mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 ' mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 End Sub
And to be complete a piece of the sub that send the cellnumbers to the class:
Option Explicit Dim Component(50) As String Dim f Dim Bestand As String Dim i As Integer Dim Cell As String Dim AantalComp As String Dim Widht As Integer Sub CellNameProcess() Dim j As Integer Dim CellName As String Dim PlaceCell As clsPlaceCell Set PlaceCell = New clsPlaceCell Dim WidhtCalc As Integer WidhtCalc = 0 For j = 0 To AantalBox1.Value PlaceCell.SetCellName (Cell) PlaceCell.Breedte = WidhtCalc WidhtCalc = WidhtCalc + Widht CommandState.StartPrimitive PlaceCell Next j AantalBox1.Value = 1 End Sub Private Sub lblComponenten_Click() End Sub Private Sub Label6076_Click() 'used Cell = "92.7000.230" Widht = 18 Call CellNameProcess End Sub
Hi,
Thanks for the quick reply's.
Yes John, All I want to do is place a set number of sells in an Array next to each other.
Thanks to the brilliant idea RobertArnold gave to me I was able to already run a quick test, ( Numbers in the for loops are still hardcoded ) and it works like a charm. Now I get five cells in the drawing in stead of one. Perfect. For those who are interested here's the code:
Option Explicit Dim CellName As String Public Breedte As Integer Implements IPrimitiveCommandEvents Public Sub SetCellName(Cell As String) CellName = Cell End Sub Private Sub IPrimitiveCommandEvents_Cleanup() End Sub Private Sub IPrimitiveCommandEvents_DataPoint(point As Point3d, ByVal View As View) Dim j As Integer Dim atPoint As Point3d atPoint.Y = point.Y atPoint.X = point.X 'draw the cell For j = 1 To 5 Dim oCellEl As CellElement Set oCellEl = CreateCellElement3(CellName, atPoint, True) ActiveModelReference.AddElement oCellEl oCellEl.Redraw point.X = point.X + Breedte atPoint.X = point.X Next j End Sub Private Sub IPrimitiveCommandEvents_Dynamics(point As Point3d, ByVal View As View, ByVal DrawMode As MsdDrawingMode) 'method called to show dynamics Dim j As Integer Dim atPoint As Point3d atPoint.Y = point.Y atPoint.X = point.X ' display a temporary cell For j = 1 To 5 Dim oCellEl As CellElement Set oCellEl = CreateCellElement3(CellName, atPoint, True) oCellEl.Redraw DrawMode point.X = point.X + Breedte atPoint.X = point.X Next j End Sub Private Sub IPrimitiveCommandEvents_Keyin(ByVal KeyIn As String) End Sub Private Sub IPrimitiveCommandEvents_Reset() ' method called when the reset event occurs CommandState.StartDefaultCommand frmEltakoComp.Show End Sub Private Sub IPrimitiveCommandEvents_Start() 'method called at the start of the command 'Dim point As Point3d Dim c As Integer c = 0 ShowCommand "Place Cell" CommandState.EnableAccuSnap CommandState.StartDynamics frmEltakoComp.Hide End Sub
And since I'm here, although I'ts probably better to open a new toppic. At he end of the code I hide or show a userform. Is there a way to have the name of the userform replaced with a variable?
Leo van der Hoeven said:Is there a way to have the name of the userform replaced with a variable?
That's a generic VBA question. A web search may reveal the answer.
In the UserForm.Initialize method, set its caption...
UserForm.Initialize
Dim name As String name = "Leo" Me.Caption = name
Regards, Jon Summers LA Solutions
Hi Jon,
Thanks for the Idea, but unfortunadly it doesn't seem to work.
When I try it this way I get a type mismatch error. I have already searched the web quite a bit for this, and for as far as I understand it the problem lies in the fact that a userform is an object, and it seems to be a problem to atach a string variable to the name of an object.
But I think where going of topic with this so it's probably better to open a new thread for this.
I have a custom dialog box called "Working". This code was able to work:
Sub testme() Load Working Working.Caption = "New Name" Working.Show End Sub
--Robert
Leo van der Hoeven said:it seems to be a problem to atach a string variable to the name of an object
You should describe more accurately what you mean by that. A UserForm is a VBA class or object. It has a visible Caption but its internal name is visible neither to the user nor the programmer (you).
UserForm
Caption
With any VBA object, including a UserForm, you can add your own data to the class definition...
' Class Module MyUserForm Private m_strLeo As String Public Property Let Leo (ByVal name As String) m_strLeo = name End Property Public Property Get Leo () As String Leo = m_strLeo End Property
Leo van der Hoeven said:unfortunadly it doesn't seem to work. When I try it this way I get a type mismatch error
unfortunadly it doesn't seem to work.
When I try it this way I get a type mismatch error
You haven't posted the relevant code from your UserForm. Here's a post in Stack Overflow that shows how to set a UserForm caption in Excel. It's the same with MicroStation VBA.
Hi Guys,
I tried the idea wit the Caption and ideed I can change the caption on the userform. But I'm afraid my question wasn't clear enough, because that's not what I'm trying to do.
Wat I'm trying to do is make the class I'm using to place the cell in such a manner that it can be used in all the mvba projects where using ( 26 ). They all have a button in the Menubar wich opens a userform, where we can select te cells that have to be drawn, and a class which does the actual inserting of the cells in the drawing. The same class is used in all the projects, and only the last lines of of the last two subs are different.
This are the lines that hide and show the userforms, wich is needed so the whole drawing can be seen while placing the cells. So I thought that if I changed the name of the userform in those lines into a variable all my classes would be the same.
I've inserted the code below, for as far as I have it now, the working lines in the lasst two subs are commented out, and the two lines after them give me the "invalid qualifier" error.
So here is the class:
Option Explicit Dim CellName As String Public cWidht As Integer Dim FormName As String Implements IPrimitiveCommandEvents Public Sub SetCellName(Cell As String) CellName = Cell End Sub Public Sub setFormName(frmName As String) FormName = frmName End Sub Private Sub IPrimitiveCommandEvents_Cleanup() End Sub Private Sub IPrimitiveCommandEvents_DataPoint(point As Point3d, ByVal View As View) Dim j As Integer Dim atPoint As Point3d atPoint.Y = point.Y atPoint.X = point.X 'draw the cell For j = 1 To 5 Dim oCellEl As CellElement Set oCellEl = CreateCellElement3(CellName, atPoint, True) ActiveModelReference.AddElement oCellEl oCellEl.Redraw point.X = point.X + cWidht atPoint.X = point.X Next j End Sub Private Sub IPrimitiveCommandEvents_Dynamics(point As Point3d, ByVal View As View, ByVal DrawMode As MsdDrawingMode) 'method called to show dynamics Dim j As Integer Dim atPoint As Point3d atPoint.Y = point.Y atPoint.X = point.X ' display a temporary cell For j = 1 To 5 Dim oCellEl As CellElement Set oCellEl = CreateCellElement3(CellName, atPoint, True) oCellEl.Redraw DrawMode point.X = point.X + cWidht atPoint.X = point.X Next j End Sub Private Sub IPrimitiveCommandEvents_Keyin(ByVal KeyIn As String) End Sub Private Sub IPrimitiveCommandEvents_Reset() ' method called when the reset event occurs CommandState.StartDefaultCommand 'frmEltakoComp.Show FormName.Show End Sub Private Sub IPrimitiveCommandEvents_Start() 'method called at the start of the command Debug.Print FormName ShowCommand "Place Cell" CommandState.EnableAccuSnap CommandState.StartDynamics 'frmEltakoComp.Hide FormName.Hide End Sub
and here is a piece of the module where the info for the class is comming from:
Option Explicit Dim Component(50) As String Dim f Dim Bestand As String Dim i As Integer Dim Cell As String Dim AantalComp As String Dim Widht As Integer Private Sub UserForm_Initialize() ' Dim frmName As String ' frmName = "frmEltakoComp" ' Me.Caption = frmName ' Dim PlaceCell As clsPlaceCell ' Set PlaceCell = New clsPlaceCell ' PlaceCell.cfrmName = frmName Dim WorkspaceRoot As String Const strWORKSPACEROOT As String = "_USTN_WORKSPACEROOT" WorkspaceRoot = ActiveWorkspace.ConfigurationVariableValue(strWORKSPACEROOT, True) Bestand = WorkspaceRoot & "Standards\data\" i = 0 f = FreeFile ' koppel de cell library AttachCellLibrary "92", msdConversionModePrompt 'Open a file for reading 'en vul de lijst met componenten Open Bestand & "EltakoComp.ini" For Input As f Do Until EOF(f) Line Input #f, Component(i) lstComponenten.AddItem Component(i) i = i + 1 Loop Close f End Sub Sub CellNameProcess() Dim frmName As String Dim CellName As String Dim PlaceCell As clsPlaceCell Set PlaceCell = New clsPlaceCell frmName = "frmEltakoComp" PlaceCell.SetCellName (Cell) PlaceCell.setFormName (frmName) PlaceCell.cWidht = Widht CommandState.StartPrimitive PlaceCell AantalBox1.Value = 1 End Sub Private Sub Label6076_Click() 'used Cell = "92.7000.230" Widht = 18 Call CellNameProcess End Sub
You can have multiple vba files loaded a the same time. Why can't you put this into its own mvba file and use it independently of the 26 projects? That way, when you make a change to it, you can make it once instead of 26 times.
Hi Robert,
I thought of that to, but wasn't shure if it was possible. I'm working here with a setup one of my colleges built some 15 years ago, and I now I'm no expert, but I'm afraid he wasn't either since i keep finding thing I think he schould have done, but for the most part it's working.
But even if I could use the same class in all the MVBA's I'd still have the problem with the variable in the name of the userform, or maybe if I can get Microstation to hide all the userform, and remember wich ones were open, and open them all again after the reset ( right click ). I did some more googling and it seems it's inpossible to change the name of a userform at runtime, at least thats wath this guy is saying about it in excel
https://www.excelanytime.com/excel/index.php?option=com_content&view=article&id=126:excel-userform-and-controls-properties-setting-control-properties-at-design-time-or-run-time&catid=79
So perhaps we should just leave it at this. It would have been nice, but it's just a minor nuisance. And I'm verry happy I got the multiple cell placing workin, that's what it all was for to begin with