Design forum
cancel
Showing results for 
Search instead for 
Did you mean: 

Using GDL Data I/O Add-on to list in layouts

Matthew Johnson
Booster
I have two objects, one is a marker that users record data into and the second is a listing object that is supposed to take the data from all the markers on a layout page and list them in order. (For those that haven't guessed already I'm working on a revisioning system)

The marker object uses a Data I/O to push the information out to a text file;
ch1 = OPEN ("DATA", "RevisionControl.txt", "MODE = WA")
OUTPUT ch1, GLOB_INTGUID, 1, LayoutID, LayoutNumber, LayoutName, RevID, RevSub, RevNote, RevDate, RevPerson
CLOSE ch1
I'm using the GLOB_INTGUID as the data key because this is then a unique number for each marker that can be updated in the database if the marker object is modified. The LayoutID, LayoutNumber and LayoutName variables are requested from the layout page by the object and the various Rev__ variables are user entered data.

The list object is then supposed to pull this data in from the text file. BUT...
I can only get the INPUT command to pull in one row of data from the file and I have to know the specific key for each row to be able to pull it in.
ch1 = OPEN ("DATA", "RevisionControl.txt", "MODE = RO")
RevData = INPUT (ch1, "???", 1, LayoutID, LayoutNumber, LayoutName, RevID, RevSub, RevNote, RevDate, RevPerson)
CLOSE ch1
Once I find a way to get multiple rows of data in (to an array?) I then need to be able to filter down to just the marker data for objects on this page of the layout book.

Suggestions?
Matthew Johnson - P O W E . Architects
AC25, Windows 10 64bit
Dell Precision 5520 i7 w/ Nvidia Quadro M1200 4K dual
HP Z640 Dual Xeon E5 w/ Nvidia RTX 2070 4K
I'd rather be sailing.
12 REPLIES 12

sinceV6
Booster
Hi.

I did something like this some time ago, but just a simple notes object, that would pull data out from a text file.

You will need to loop the INPUT keyword and assign values to an array, like you said, to use the data.

I picked this code snippet up from somewhere:
 
! Example to read all string values from a file 
! and use it in a value list 
DIM sarray[] 
! file in the library, containing parameter data 
filename = "ProjectNotes.txt" 
ch1 = OPEN ("text", filename, "MODE=RO, LIBRARY") 
i = 1 
j = 1 
sarray[1] = "" 
! collect all strings 
DO 
n = INPUT (ch1, i, 1, var) 
IF n > 0 AND VARTYPE (var) = 2 THEN 
sarray = var 
j = j + 1 
ENDIF 
i = i + 1 
WHILE n > 0 
CLOSE ch1 
! parameter popup with strings 


What I did, as I was really experimenting with the CHANNEL and INPUT keywords, was to first count how many rows and columns were in the file, so I could organize data; then I used a couple of loops to put it in a two dimension array and analyzed the size (string size) of each column. This way, I could use the same object to write notes, keynotes or tabulated data from a text file.

Hope that helps.
Best regards.

Matthew Johnson
Booster
sinceV6,

Thank you for the pointer.

The issue with this procedure however is that it relies on your data source having sequential integer recordIDs starting at 1. As the data source is being created for each project by a number of objects inserted into the layout book I need to have a recordID control system that allows each marker object to have its own individual recordID (for updating to ensure the data for each object is mapped properly) but then I need to have a way to have the list object pull that data without knowing all of the recordIDs for each record.

I can't find a way to pull the records from the file line by line without knowing the recordIDs and to get it to search for all possible GUIDs would cause an infinite loop that will crash on run.
Matthew Johnson - P O W E . Architects
AC25, Windows 10 64bit
Dell Precision 5520 i7 w/ Nvidia Quadro M1200 4K dual
HP Z640 Dual Xeon E5 w/ Nvidia RTX 2070 4K
I'd rather be sailing.

sinceV6
Booster
Matthew.-

If you are writing those values, can't you use them as a filter? The way I see it, you are trying to filter with the GLOB_INTGUID -that you are using so that values get correctly mapped for output-, but I would rather write the code so that it filters the lines based on what layout the object getting the data is placed on; this way, you may have 100 placed objects throughout your layouts, but only 10 in one: those are the ones you would like listed, right?

So assign values to the array only if the layoutID value of the record matches the current layout.

Unless of course I'm not getting what you are trying to do...

Ben Cohen
Contributor
Hi Mathew

I think you need to write using 'Data' then read using 'Text'. This way you can read the entire text file.
You could also prefix your layout number and name to the GUID as database key - to get the data to sort automatically for you.
Ben Cohen

Mac and PC

Archicad (Latest Version) aus

www.4DLibrary.com.au

Matthew Johnson
Booster
Ben, Thanks for the idea. I'd missed that Data and Text use slightly different formats for extracting recordIDs.

I'm now working up a version where the recordID that is written to the file is a combination of the LayoutID, RevID and RevSub so that they are pre-ordered in the text file.

I also need to find a way to make the listing object update either automatically or by a control mechanism like a button in the UI.
Matthew Johnson - P O W E . Architects
AC25, Windows 10 64bit
Dell Precision 5520 i7 w/ Nvidia Quadro M1200 4K dual
HP Z640 Dual Xeon E5 w/ Nvidia RTX 2070 4K
I'd rather be sailing.

sinceV6
Booster
Completely missed that you were using DATA. I was always referring to using TEXT

As far as I can remember, reloading libraries would update your placed object, but in the notes object I worked, it only retrieved values from a text file. Not sure if it would work when there are other objects writing to the database (at the same time?).

Cheers!

Matthew Johnson
Booster
So I now have both objects working close to the way I want them to.

The Marker Object pushes data out and the data is ordered by page and then instance;
MASTER SCRIPT
n = REQUEST ("HomeDB_info", "", LayoutID, LayoutNumber, LayoutName, LayoutContext)

index = (LayoutID * 100) + RevID + (RevSub / 100)

ch1 = OPEN ("DATA", "RevisionControl.txt", "MODE = WA")
OUTPUT ch1, index, 1, LayoutID, LayoutNumber, LayoutName, RevID, RevSub, RevNote, RevDate, RevPerson
CLOSE ch1
The Listing Object then reads this data;
MASTER SCRIPT
n = REQUEST ("HomeDB_info", "", ThisLayoutID, ThisLayoutNumber, ThisLayoutName, ThisLayoutContext)

! Create an array to put the data in
DIM RevArray[][5]
i = 1
j = 1
RevArray[1][1] = ""

! Open the text file containing the Revision data
ch1 = OPEN ("TEXT", "RevisionControl.txt", "MODE = RO")

! Collect all strings
DO
	RevData = INPUT (ch1, i, 1, index, LayoutID, LayoutNumber, LayoutName, RevID, RevSub, RevNote, RevDate, RevPerson)
	IF LayoutID = ThisLayoutID AND RevData > 0 THEN
		RevArray[1] = RevID
		RevArray[2] = RevSub
		RevArray[3] = RevNote
		RevArray[4] = RevDate
		RevArray[5] = RevPerson
		j = j + 1
		ENDIF
	i = i + 1
	WHILE RevData > 0

! Close the data source
CLOSE ch1
Problems that still exist;
- If a marker is modified (e.g. RevSub is accidentally set at 5 and then changed to 4) it puts two entries in the database and lists them both.
- The only way to get the Listing Object to update to show the new Marker Object data is to open the Listing Object's properties and change one of the property values thereby causing it to re-build.

This could be overcome if I could somehow get the database file to reset and re-build itself from all of the objects in the layout book but this sounds like just the same hurdle that caused me to start this exercise; the lack of an ability to list objects in the Layout Book!

Is this where I have to learn to program the API?
Matthew Johnson - P O W E . Architects
AC25, Windows 10 64bit
Dell Precision 5520 i7 w/ Nvidia Quadro M1200 4K dual
HP Z640 Dual Xeon E5 w/ Nvidia RTX 2070 4K
I'd rather be sailing.

Did you read the chapters from Laurent Godel in DNCs GDL Cookbook 3; maybe there are some hints in it that may help.
http://www.nottingham.ac.uk/~lazwww/cookbook/CB_download/cookbook3download.html
Joachim Suehlo . AC12-25 . MAC OSX 10.15 . WIN10

sinceV6
Booster
Hi.
Isn't that because you are using the data as the recordID to map the values? Each time you modify a value in an object, a new record will be generated, based on what I see in your code.

Maybe I didn't explain myself before: I think you were right to use the GUID value to map the recordID, so it doesn't matter what values the object gives, they should fall in the same record; but once you have the database, instead of trying to find the GUIDs of the objects in the layout, list objects that are in the layout comparing the layoutID value to the current one.

As for the updating thing... did you try reloading libraries?

sinceV6
Booster
Hi.
I gave it a quick go and can confirm that:

1.- Using GLOB_INTGUID works to keep values correctly mapped in the database. You could use any parameter or string (like the ID) as long as you keep them consistent.
2.- Listing object updates as soon as you change any parameter in a marker object (after screen refresh -as in "pan" around-), as long as the lister is able to find the database (either loaded in the libraries, or by using DIALOG in the paramstring)

The downsides are that the list is not ordered -but could be rearranged using other commands-, and that since the database is being written by several objects, there would need to be a second (global) database so that you could delete records based on missing key values.

Matthew Johnson
Booster
Solution I'm working with now;

1. Using a button in the UI of the listing object to clear the database and then get the user to Rebuild & Regenerate (Ctrl+Shift+Alt+R) to force all markers to re-write their details to the database. This overcomes redundant entries from deleted objects and also causes all data to be completely refreshed each time you need it.
2. As the database is re-built so often the issue of using the GUID isn't critical so I'm using a generated index which allows me to sort the revisions before putting them to the array.
3. I've centralised the data file locations using a request function on project names so that the data text file can be used as a data connection into Excel for producing change log reports for contractors.

Amazing that it has taken 10 years for the idea to crystalize enough to be able to get ArchiCAD to do this very simple task...
Matthew Johnson - P O W E . Architects
AC25, Windows 10 64bit
Dell Precision 5520 i7 w/ Nvidia Quadro M1200 4K dual
HP Z640 Dual Xeon E5 w/ Nvidia RTX 2070 4K
I'd rather be sailing.

JaseBee
Advocate
Hi Matthew,

I had almost this exact idea a few weeks back, and I found this topic today after finally getting ready to build it. this stream has already been a big help, thanks.

However I have already run into a few issues, between the homeDB not allowed but sorta able to be run in the parameter script, and a ridiculous non-existent channel error that I am positive exists, to certain bit's falling over in AC19 but working fin in AC21. It's been a rolling stream of profanity hurled at the screen...

All that aside, I think I can get past them all, however the one stick in the mud I can't get past is the regeneration.

You said you use Rebuild and Regenerate to reload all the markers data after purging everything to get rid of duplicates (brilliant way to deal with that problem by the way). However I am assuming both your markers and the purging object are present on the same layout? R&R only seems to work on the active view (or at the very best all open layout tabs) Is there some way you are regenerating all layouts?

I have tried the "Run Parameter Script of all Placed Objects" but that only seems to apply to those living in model space.

Or do you just purge data layout by layout (this is the solution I'm leaning toward...)

I've said it a million times, we should be able to schedule labels, and we should be able to schedule things that are placed outside plan view... Sigh.

Thanks for you work on this subject.
Jase.
AC 24 5004 AUS
iMac OSX (10.13.6) 4.2ghz i7
8gb ram/8gb vram

Didn't find the answer? Start a new discussion

Labels

Still looking?

Browse more topics

Back to forum

See latest solutions

Accepted solutions

Start a new discussion!