Solved X and Y Coordinates (1 Viewer)

MattBaldry

Self Taught, Learn from the Forums
Local time
Today, 00:55
Joined
Feb 5, 2019
Messages
293
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

XY
1025
3040
5055
7070
22025
24040
26055
28070

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
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Yesterday, 18:55
Joined
Feb 28, 2001
Messages
27,189
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.
 

plog

Banishment Pending
Local time
Yesterday, 18:55
Joined
May 11, 2011
Messages
11,646
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:

MarkK

bit cruncher
Local time
Yesterday, 16:55
Joined
Mar 17, 2004
Messages
8,181
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
 

MattBaldry

Self Taught, Learn from the Forums
Local time
Today, 00:55
Joined
Feb 5, 2019
Messages
293
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
 

Users who are viewing this thread

Top Bottom