ComboBoxes help.

Started by vladgothe, August 07, 2012, 05:19:34 AM

Previous topic - Next topic

vladgothe

I have a csv file, from which I add values in my comboboxes. In the lisp file, I use a function to parse the csv file in a list of lists. Each list contains all the strings from a line (ex. in the csv file the line is: "1026,1017,9,Alba Iulia,1" and after parsing the file will result a list like this '("1026" "1017" "9" "Alba Iulia" "1"). In the end will result a list like this '( (list1) (list2) (list3)...(listn) where n is the maximum number of lines from the csv file.
So, for example if I want to use the value "1017" from that list, the variable will be like this: (setq var (cadr (nth posf lst))), where lst is the list with all the lists, and posf is the position of the list in the big list.
In my odcl file I have 2 forms: Form1 and Form2. In Form1 I have ComboBox4, ComboBox5 and ComboBox6 (the ones from upleft).
ComboBox4 has a predefined list and an OnSelChanged event. In the csv file, the last value from each line (in this case "1") has the value of (1+ ItemIndexOrCount from that OnSelChanged event.) So, when you select ALBA, for instance, which has the value of ItemIndexOrCount of 0, in the csv file it will have the value "1", when you select ARAD which has the value of ItemIndexOrCount of 1, in the csv file will have the value "2" etc. The last value from each line is stored in a variable called jn2.
The second value from each line in the csv file is stored in a variable called sirsup. So, when I select a value from ComboBox4, I read the csv file and if (1+ ItemIndexOrCount) is equal with jn2, and if sirsup has less than 4 letters, the fourth value from each line in the csv file is added in ComboBox5 and is stored in a variable called string1.
For example, when i select ALBA in ComboBox4, the ComboBox 5 will have the values: "Mun Alba Iulia|Mun.Blaj|Mun. Aiud etc."
The first value from each line in the csv value is stored in a variable called siruta. You can observe that in the next line sirsup has more than three letters and is identical with siruta from the previous line.
What I want is:
-when I select a value from ComboBox5, I want ComboBox6 to be filled only with the variables string1 from that lines in the csv file which have sirsup value identical with siruta value of the string from ComboBox5.
So, I give an example to be understood:
-In ComboBox4 I select ALBA (which is the first value).
-In ComboBox5 I select Mun. Alba Iulia
-So, I want in ComboBox6 to appear the following values: "Alba Iulia|Barabant|Micesti|Oarda|Paclisa" and then stop because the next line has a string1 which was added in ComboBox5.
I attach here the csv file, the lisp file and the odcl file. I mention that the comments from the lisp file and the forms interface are in romanian language. The lisp file is not complete, but is working.
I apologise for my poor english and I hope my post will be understood.

Fred Tomke

Hi, your zip file is empty.
Regards, Fred
Fred Tomke
Dipl.-Ing. (FH) Landespflege

[ landscaper - landscape developer - digital landscape and urban design]

Fred Tomke

Hi, I'm not sure if I understood right but I'd try to get the right list items using vl-remove-if or vl-remove-if-not.
Regards, Fred
Fred Tomke
Dipl.-Ing. (FH) Landespflege

[ landscaper - landscape developer - digital landscape and urban design]

vladgothe

#3
After I attach the zip file, It shows me that it has 0 KB, but it has 147 KB. The zip file contains the csv file. I changed the extension in txt.

Fred Tomke

#4
Hi, my (and your) question is how to filter Alba Iulia,Barabant,Micesti,Oarda,Paclisa from the csv list. Do these items have a foreign key to the selected item of combobox5?

Have you ever thought about using a database (SQLite, dBase, MS Access, ...) and accessing it by Lisp?

I'd prefer to do it this way:

Table JUDET
~~~~~~~~
ID | NAME | other fields

Table UAT
~~~~~~
ID | ID_JUDET | NAME | other fields

for 1:n relations
Table SAT_ORAS
~~~~~~~~~~
ID | ID_UAT | NAME | other fields

for n:m relations
Table SAT_ORAS
~~~~~~~~~~
ID | NAME | other fields

Table REF_SAT_ORAS
~~~~~~~~~~~~~
ID | ID_SAT_ORAS | ID_UAT

Using SQL-Statements you can get all the items you need:
(for 1:n-relations)
select ID,NAME from SAT_ORAS where ID_UAT = 1764

If you HAVE to use the csv, you can do the things using vl-remove-if-not:
Code (autolisp) Select

(setq lstItems (vl-remove-if-not '(lambda (lstCSVItem) (= (nth 3 lstCSVItem) 1764)) lstCSV))
(dcl_combobox_clear Documentatii_Form1_ComboBox6)
(dcl_ComboBox_AddList Documentatii_Form1_ComboBox6 lstItems)


Hope that helps!
Regards, Fred
Fred Tomke
Dipl.-Ing. (FH) Landespflege

[ landscaper - landscape developer - digital landscape and urban design]

roy_043

@ vladgothe:
Your question is actually Lisp-related and not ODCL-related.

There are some basic problems with your code:
1. You use too many global variables.
2. You are merging functions that are better kept separated.

Keeping the csv-file approach, there is nothing wrong with that, I would suggest this basic structure to address your problem:

Code (autolisp) Select
(princ "\nLoading ODCL ... ")
(command "OPENDCL")

(defun c:DOC ( / allDataList FilteredForCombo5DataList FilteredForCombo6DataList)
  (princ "\nLoading data ... ")
  (setq allDataList (ReadCSV (findfile "Siruta.csv")))
  (dcl_Project_Load "Documentatii" T)
  (dcl_Form_Show Documentatii_Form1)
  (princ)
)

(defun ReadCSV ( filename / _replacequotes _csv->lst file line lst)
;; ... = Code left out
;; ...
;; ... End the ReadCSV function here:
;;Aceasta este lista cu toate liniile din fisierul "Siruta.csv"
(reverse lst)
)

(defun c:Documentatii_Form1_ComboBox4_OnSelChanged (ItemIndexOrCount Value / jnr)
  ; ...
  ; ...
  (setq jnr "1")
  ; ...
  ; ...
  (setq FilteredForCombo5DataList
    (vl-remove-if-not
      '(lambda (a)
        (and
          (= (last a) jnr)
          (<= (strlen (cadr a)) 3)
        )
      )
      allDataList
    )
  )
  ; ...
  ; ...
  (FunctionToFillCombo5 FilteredForCombo5DataList) ; Create a separate function to fill the combo.
  ; ...
  ; ...
)
 
(defun c:Documentatii_Form1_ComboBox5_OnSelChanged (ItemIndexOrCount Value / pickedItemData sirsup)
  (setq pickedItemData (nth ItemIndexOrCount FilteredForCombo5DataList))
  (setq sirsup (car pickedItemData))
  (setq FilteredForCombo6DataList
    (vl-remove-if-not
      '(lambda (a)
        (= (cadr a) sirsup)
      )
      allDataList
    )
  )
  ; ...
  ; ...
  (FunctionToFillCombo6 FilteredForCombo6DataList) ; Create a separate function to fill the combo.
  ; ...
  ; ...
)



vladgothe

Thank you very much roy_043. Your code snippet does exactly what I want and made my application much faster and reliable. I am not a programmer, I am a drafter, but I have some basic knowledge in Lisp, and I started to use OpenDCL because I am too lazy to learn simple DCL. And now it's compatible with AutoCAD 2013, which is a great plus.