# SolvedX and Y Coordinates (1 Viewer)

#### MattBaldry

##### Self Taught, Learn from the Forums
Hi forumers,

I have a modified drag and drop planner we use at work that places new activities on the screen with an X and Y coordinate to place it when added.

I am trying to figure out how to work out the next X and Y values based on the last values in the table.

X starts at 10 and increases 3 more times in 20s then increases by 150
Y starts at 25 and increases 3 more times in 15s then resets back to 10

 X Y 10 25 30 40 50 55 70 70 220 25 240 40 260 55 280 70

So the next X and Y would be 430 | 25. Does anyone have an idea on how I could make this work so when a new job is added to the planner, it allocated the correct X and Y?

Something like

IIf LastOfY = 70 then X = LastOfX + 150 And Y = 25 else Y = LastOfY +20 And X = LastOfX +15?

I have never written anything like this so not sure of the correct VBA or layout.

Once the jobs are moved onto the calendar part, the X and Y coordinates for that job become 0 | 0 and all the others are moved to a new correct position, but the planner already does this. I am only looking for new jobs added.

I really hope I have made something close to sense here.

~Matt

This gets a little complex. I can't show you code because of the NDA I was under. I don't own the code so can only describe it, not show it.

You have this problem: You want to allocate something to a work area. What you want to allocate will occupy a rectangle, so you might as well just allocate a rectangle. But here is the other side of this. You are allocating these rectangles to fill another area which is ALSO a rectangle. The trick is to then keep track of where you are.

You start with position (0,0) for the TOP and LEFT corner of the rectangle, because that is where the next (first) allocation goes. BUT you also have to track the HEIGHT and WIDTH of the rectangles. So your first allocation is to add (20,15) to the starting TOP & LEFT and compare the result to the containing rectangle to verify that this addition will fit. At the time when your new rectangle would step outside of the container, you have to do whatever is the next step, which is for example, your "bump X by an amount and reset Y back to some amount"

The way I did it was I created a structure where I computed TOP, LEFT, BOTTOM, and RIGHT (the latter by adding TOP to HEIGHT and LEFT to WIDTH) to establish starting AND ENDING positions for the rectangles. You can create functions and subroutines that pass user-defined data types, which is what I did. I created a "container rectangle" that was really just a rectangle to establish boundaries. Then when I was about to create a new data rectangle, I called a routine with the height and width as two "ordinary" parameters, an empty rectangle-corner data element, the most recent rectangle I had allocated, and the container rectangle. It did all the math and either put the new rectangle's coordinates in place or returned an error code if I had one too many rectangles.

Sounds complex? Yeah, it kind of got messy sometimes, but once I got it to work, it made my forms look really slick, because what I was doing was placing command buttons dynamically based on the state of the form. For example, if the form wasn't dirty, a CLOSE button was there - but the SAVE button wasn't. If you dirtied the form, CLOSE vanished, but SAVE and UNDO became visible next to each other. There were up to half a dozen possible command buttons and they moved according to the form state. It was well-accepted by my users.

I think you just MOD the number of records in the table and use it like so:

Code:
``````int_Records = DCount("X", "YourTable") MOD 4

int_Y = 25 + (int_Records*15)

int_X = int_LastX + 20
if (int_Records==0) int_X = int_X + 130``````

Last edited:
I was curious how hard this would be. Here's a class module that does it...
Code:
``````Private Const X_START As Long = 10
Private Const X_STEP As Long = 20
Private Const X_COUNT As Integer = 4
Private Const X_LEAP As Long = 150

Private Const Y_M As Single = 0.75
Private Const Y_C As Single = 17.5

Private x_ As Long

Property Get X() As Long
X = x_
End Property

Property Get Y() As Long
Dim tmp As Long
tmp = X Mod (X_LEAP + (X_COUNT - 1) * X_STEP)
Y = tmp * Y_M + Y_C
End Property

Sub MoveNext()
GetNext_X x_
End Sub

Sub SetStartX(Number As Long)
x_ = Number
End Sub

Function ToString() As String
ToString = X & ", " & Y
End Function

Private Sub GetNext_X(ByVal Number As Long)
x_ = X_START
Do While x_ <= Number
DoSteps Number
If x_ <= Number Then x_ = x_ + X_LEAP
Loop
End Sub

Private Sub DoSteps(Number As Long)
Dim i As Integer

Do While i < X_COUNT - 1 And x_ <= Number
x_ = x_ + X_STEP
i = i + 1
Loop
End Sub``````

Here's code you might use to test the class...
Code:
``````Private Sub Test1234()
Dim tmp As New cMySeries
Dim i As Integer

For i = 0 To 15
tmp.MoveNext
Debug.Print tmp.ToString
Next
End Sub``````

Thanks for the help guys.

In the end I figured out where the existing module was that did this for his right click menu and called the into my own new form and it works.

~Matt

Replies
2
Views
524
Replies
26
Views
1,073
Replies
8
Views
768
Replies
11
Views
924
Replies
11
Views
768