05.06.2011 19:05    

pitsss
Kod:

(defun c:soru ()
(setq dosyaadı (getstring "data dosyası adı giriniz : "))
(setq dosyayeri (strcat (getvar "dwgprefix") dosyaadı ".txt"))
(setq txt (open dosyayeri "w"))
(while (> 10)
(setq yz(entsel"\nyazı seçiniz !"))
(setq yz(entget(car yz)))
(setq yazzz (cdr(assoc 1 yz)))
(setq ent (entsel "çizgi seçiniz."))
(if (null ent);ENT DEĞERİ BOŞ İSE PROGRAMA DEVAM EDİLECEK 
(progn
); end progn
);end if
(setq ent1 (entget (car ent)));ENT LİSTESİNİN İLK LİSTESİ ALINIYOR VE ENT1 DİYE BİR LİSTE OLUŞTURULUYOR.
(setq bas (cdr (assoc 10 ent1)); ÇİZGİNİN BAŞLANGIÇ NOKTASI OLUŞTURULUYOR.
son (cdr (assoc 11 ent1));  ÇİZGİNİN BİTİŞ NOKTASI OLUŞTURULUYOR
boy (distance bas son);  ÇİZGİNİN BOYU HESAPLANIYOR
); SETQ BAS İLE BAŞLAYAN SET İN BİTİŞ PARANTEZİ
(initget "a1 a2 a3 a4")
(setq isim (getkword "n[a1/a2/a3/a4]: "))(terpri)
(setq P1 (getpoint "n birinci nokta: "))(terpri)
(setq P2 (getpoint "n ikinci nokta : "))(terpri)
(command "line" p1 p2 "")
(setq cboy (distance p1 p2))
(setq yz1(entsel"\ndiğer yazıyı seçiniz !"))
(setq yz1(entget(car yz1)))
(setq yazzz1 (cdr(assoc 1 yz1)))
(write-line
(strcat YAZZZ "\t" YAZZZ1 "\t" isim "\t" (rtos boy 2 0) "\t" (rtos cboy 2 0))
txt
)
);WHİLE (> 10) END
(close txt)
) ;end defun


merhaba arkadaşlar autolisp te yeniyim ve bazı sorunlar var bir türlü çözemedim. yardımcı olursanız sevinirim.
yukarıdaki kodlarım çalışıyor ancak. bazı sorunlarım var. mesela
yz entsel ile yazıyı seçtiriyorum. fakat kullanıcı yanlışlıkla yazıyı değil de boşluğu tıkladı ya da line a tıkladı diyelim.Ozaman programım hata veriyor.
aynı şekilde line seçme işleminde de geçerli bu.
aslında istediğim. text seçme zorunlu olsun. ama line seçme zorunlu olmasın. mesela line seçmek istemediğinde boşluğa ya da sağ tuşa bastığında line ı seçmeden komut çalışmaya devam etsin. bunu nasıl yapabilirim acaba ?

05.06.2011 21:10    

ehya
Bu işlem için "errno" sistem değişkenini kullanmak gerekir. biraz bahsetmek gerekirse tek nesne seçimi yapılırken boş bir yere tıkladığınızda errno sistem değişkeni 7 numarayı alır. mouse'un sağ tuşuna bastığınızda ise 52 değerini alır.
bununla beraber entsel kodunun başına while kullanırken döngüye şart bağlamalısınız. örneğin şu değer nil ise döngüye gir diye.
bundan sonra da entsel komutunu çalıştırır ve nesne seçimi yapmasını istersiniz. buradaki seçimde nesne seçilir yada seçilmez.
seçim yok ise errno değerine bakar, 7 ise while başındaki döngüye tekrar nil olmasını ister, 52 ise t yani döngü yapma deyip komutun bitirilmesini sağlarsız.
ancak seçim var ise, seçilen nesnenin dxf kodlarından yada veri tabanından nesne adını öğrenir, seçilen nesne text değil ise nil deyip tekrar başa dönmesini sağlayabilirsiniz. text ise yapmak istediğiniz işlemi yaptırırsınız.

bununla ilgili olarak daha önceden yazmış olduğum bir lispi paylaşayım. işinize yarayacaktır.

ayrıca teşekkür ederim. uzun zamandır lisp istemek yerine, lisp hakkında soru soran ve hatanın nasıl giderileceği konusunda bilgi isteyen kişisiniz.
umarım bundan sonra böyle bilgi isteyen kişilerin sayısı artar..


Kod:

(defun c:TC ()
  (setvar "cmdecho" 0)
  (vl-load-com)
  (command "undo" "group")
  (setq tc_deger (getint "\n1.numara:"))
  (if (= tc_deger nil)
    (progn)
    (progn
      (setq tc_ent1 nil)
      (while (= tc_ent1 nil)
(setq tc_ent (car (entsel "\nYazıyı seçin:")))
(if (= tc_ent nil)
  (progn
    (if (= (getvar "errno") 7)
      (progn
(setq tc_ent1 nil)
(setvar "errno" 0)))
    (if (= (getvar "errno") 52)
      (progn
(setq tc_ent1 t)
(setvar "errno" 0)))
   
  )
  (progn
    (setq tc_tani (cdr (assoc 0 (entget tc_ent))))
    (if (/= tc_tani "TEXT")
      (progn
(princ "\nSeçilen nesne YAZI değil...!!!")
(setq tc_ent1 nil))
      (progn
    (setq tc_data (vlax-ename->vla-object tc_ent))
    (vla-put-textstring tc_data tc_deger)
    (setq tc_deger (+ tc_deger 1))
  )
)
      )
    )
  )))
  (command "undo" "e")
  (princ)
)
(princ)

06.06.2011 17:29    

pitsss
Çok teşekkür ederim cevabın için. kodları kendime uyarlamaya çalışacağım umarım başarılı olurum. hazır istekler benim için uygun değil. çünkü benim anlamadığım bir kod benim hiçbir işime yaramaz. o yüzden kendim öğrenmeye çalışıyorum. bunu yaparken de genelde hazır kodların benim işime yarayacak olanlarını alıyorum. ilk önce çalıştırıyorum. sonra da kullandığım kodlarda ki fonksiyonların anlamlarına bakıp ne işe yaradıklarını öğreniyorum. yani tamamen kendi ihtiyaçlarıma göre kodları öğreniyorum. belki pek yararlı olmaz bu yöntem ama. hiç kod yazmadan bunlar ne işe yarar diye tek tek öğrenmek sıkıcı geliyor bana ya da ben başaramıyorum.
kodları kendime göre düzenledikten sonra burada paylaşacağım. ayrıca burada ki hata kodlarının hepsini öğrenebileceğim bir link var mı?

06.06.2011 18:52    

ehya
Ben bu lisp işine girdiğimde yaşım 18di. kimseden yardım almadan kurcalayarak kodların ne anlama geldiğini öğrendim. zaman içerisinde de kendimi geliştirdim. autocad'in yardım tablosu benim en büyük yardımcım idi. oradaki kodlardan aklıma kalanları zaman içerisinde kullanarak kendimi geliştirdim.
burada bahsettiğim errno değişkenini de bu şekilde öğrendim deneme-yanılma yani. o zamanlar internette bu bilgiler yoktu. şimdi ise yabancı kaynak da olsa mutlaka bilgi bulabilirsiniz.
"errno" sistem hataları ile ilgili bilgiler için aşağıdaki linkten bulabilirsiniz.



Linkleri görebilmek için ÜYE olmalısınız.

06.06.2011 21:11    

pitsss
Ozaman ben de senin yolundan gideyim. :) her nekadar yaşım 18 olmasa da . öğrenmenin yaşı yoktur demişler.
cevabın için tekrar teşekkürler.

verdiğin kodları kurcaladım ve kendime göre birşeyler ortaya çıkardım. umarım bi yanlışlık yapmamışımdır. kodları kendime göre açıkladım. belki yararı olur.
Kod:

(defun c:sez ()

(setq yznil nil) ; yznil ilk değeri boş olarak atandı. bu sayede while döngüsü başlatılmış oldu
;yznil eğer boş ise döngüye başla.
      (while (= yznil nil) ;while 1
(setq yz(entsel"\n text seç !")); text seçme işlemi
;eğer yz boş ise yapılacaklar:
(if (= yz nil) ;if 2
(progn ;p2; yazı boş ise
   
(if (= (getvar "errno") 7); if 3 ; errno 7 hiçbirşey seçmemişse. yani boşluğu tıklamışsa
      (progn ;p3
(setq yznil nil); yznil değeri tekrarnil yapılıyor ve döngü tekrar sağlanıyor.
(setvar "errno" 0); sanırım errno yu sıfırlıyoruz. tekrar döngüye girdiğinde en son errno sayısı kalmasın diye.
(princ " bi yaziyi seçemedin bee :D"); boşluğa tıkladığımı  anlayım diye öylesine yazdım bi önemi yok. sileceğimde zaten :)

) ;end p3
) ;end if3
    (if (= (getvar "errno") 52) ;if 4; errno 52 yani sağ tuş tıklama
      (progn ;p4;errno 52 doğru ise yapılacaklar
(setq yznil t); errno 52 ise yznil true değerini alacak ve döngü sonlanmış olacak.
(setvar "errno" 0); errno yu karışıklık olmasın diye sıfırlıyoruz.
);end p4
);end if 4
   
  ) ;end p2

  (progn ; p5; yazı boş ise p2 deki işlemler yapıldı şimdi ise birşeyler seçtiğimiz zaman yapacağımız işlemler:
    (setq tc_tani  (cdr (assoc 0 (entget (car yz))))); text kontrolü için yz ye işlemler uyguladık.

        (if (/= tc_tani "TEXT") ;if 5; tc_tani text değil ise yapılacaklar
      (progn ;p6
(princ "\nSeçilen nesne YAZI değil...!!!"); nesnenin yazı olmadığını söyledik.
(setq yznil nil); döngüye tekrar girelim diye yznil değerini nil yaptık
);end p6
      (progn ;p7; tc_tani tezt ise yapılacaklar:
    (princ " pitsss seni tebrik ediyorum, hele şükür text i seçebildin.:)"); buraya istediğiniz işlemleri yazabilirsiniz. mesela yz nin TEXT değerini alabilirsiniz.şu şekilde(setq tc_tani  (cdr (assoc 1 (entget (car yz)))))
(setq tc_tani  (cdr (assoc 1 (entget (car yz)))))
(princ tc_tani )
(setq yznil t); yznil true demez isek döngü sonsuz döngü olur.
  ) ;end p7
); end if5
      ) ;end p5
); end if 2
);end while 1
); end defun

pitsss (06.06.2011 21:34 GMT)

06.06.2011 21:43    

ehya
Genel anlamda kodlamada gördüğüm birkaç noktaya değinmek istedim. gerekli bilgileri resim üzerinde göstermek daha güzel olacaktır.

08.06.2011 17:36    

pitsss
Yardımların için çok teşekkür ederim ehya.

08.06.2011 18:48    

ProhibiT
Bazı problemlerinizi çözdüğünüzü, ilerleme kaydettiğinizi keyifle izledim.

bir kaç noktaya dikkatinizi çekmek isterim.

ilk yazdığınız kod içinde (while (> 10)... ifadesi var. böyle bir ifade olmaz, 10'dan büyük olması kontrol edilecek nedir? bu tür kontrol ifadeleri (operatör parametre1 parametre2 ... parametren) formatında en az iki parametreli olur. özel halleri vardır; (if eob) dersek, eob değişkeni nil ise nil, nil değilse true değerini elde ederiz. ama sizin yazdığınız gibi, (> 10) dersek hangi değerin 10'dan büyük olduğunu sınamak istediğimizi autolisp bilemez.

(if (null ent)
(progn
); and progn
);end if

bu bölümde bir kere (null ent) diye bir ifade olmaz. ent değişkeni ile null değeri arasında ne tür bir ilişkiyi kontrol ediyoruz?
bu bölüm doğru olsa bile, hiç bir şey yapmamak için, hiç bir şeyi kontrol ettirmeme gibi bir yöntem olamaz.

burada ent değeriniz ne olursa olsun, program bir sonraki adımdan devam edecektir. sizin araya koyduğunuzu (if... anlamsız ve boş bir bölümdür? yazılmasının bir anlamı ve gereği de yok...

öncelikle fonksiyon akışını ve mantığını çok net olarak kurmalısınız, ilk paylaştığınızı fonksiyonda böyle bir algoritma bütünlüğü olmadığı için autolisp komutlarının detayında boğulmuşsunuz.

ilk mesajınızda "yukarıdaki kodlarım çalışıyor ancak. bazı sorunlarım var" demişsiniz. yukarıda bahsettiğim if ve while direktiflerinin kontrol bölümleri yanlış olduğu için yazdıklarınızın çalışıyor olması mümkün değil. bir şeye dikkatinizi çekerim! yazılan fonksiyonun hata koduyla sonlanmıyor olması onun çalıştığını ve doğru olduğunu göstermez. hata ile sonuçlanmayan fonksiyon ne yapıyor? hedeflenen işlemi gerçekleştiriyor mu?

ehya hocamın verdiği örneklerle bir kademe daha olayın içine girdiğinizi düşünerek bunları şimdi yazıyorum. ilk fonksiyonunuzda ne yapmak istediğinizi tam olarak adım adım ifade ederseniz, buradan birlikte fonksiyonunuzu en sade haliyle yeniden yazıp, hem sizin hem de konuya ilgi duyan arkadaşlarımızın faydalanabilecekleri bir örnek oluşturulur diye düşünüyorum.

zaman zaman, ilgi duyan arkadaşlara örnek olabilecek kodlama örnekleri paylaşıyoruz.
sıklıkla kullandığımız extend işlemini yaparken, ya epeyce uğraşarak boundary seçiyoruz, ya da kestirmeden enter girip boundary olarak all seçiyoruz. bu seferde extend edeceğimiz objelerin çoğunu bir kaç adımda, bir kaç defa ucundan tıklayarak işlemi gerçekleştiriyoruz. bu noktada bir detaya dikkatinizi çekmek isterim. her zaman olmasa bile genelde extend edeceğimiz objeleri kendi layer'ındaki başka objelere kadar uzatıyoruz. dediğim gibi, her zaman böyle değil ama, genelde mesela duvar layer'ındaki bir çizgiyi gene duvar layer'ındaki diğer objelere kadar uzatıyoruz. Bahsettiğimiz işlemi çok basit ve sade bir şekilde açıklamalı olarak yazmaya çalışalım;
Kod:

(defun c:Lex (/ Eob Lyr) ; eOb ve Lyr değişkenlerini local olarak tanımladık.
  (setq eOb (entsel)     ; Bir obje seçiyoruz.
        Lyr (cdr (assoc 8 (entget (car eOb))))
                         ; Seçtiğimiz objenin Layer'ını öğreniyoruz.
  )
  (while eOb             ; Eob objesi True olduğu sürece (nil olmadığı sürece)
                         ; tekrarlanacak bir döngü kuruyoruz.
    (command "_.Extend"  ; Extend komutunu çalıştırıyoruz.
             (ssget "x" (list (cons 8 Lyr)))
                         ; Extend işleminde boundary olarak,
                         ; Lyr Layer'ındaki tüm objeleri seçiyoruz,
             ""          ; Bondary seçimini sonlandırdık.
             eOb         ; seçili objeyi eOb ilgili bondary'ye uzattık.
             ""          ; extend komutunu sonlandırdık.
    )
    (setq eOb (entsel))  ; Aynı boundary setine göre extend uygulamak üzere,
                         ; yeni obje seçiyoruz.
                         ; Yeni obje seçmezsek (sağ tıklar veya boş yere
                         ; tıklarsak, eOb değeri nil olacağından,
                         ; döngümüz sonlandırlacak, fonksiyon sona erecektir.
  )
  (princ)                ; Fonksiyondan temiz bir çıkış sağlamak için,
                         ; boş bir satır yazdırıyoruz.
)

Bu fonksiyonu daha derli toplu yazarsak;
Kod:

(defun c:Lex (/ Eob Lyr)
  (setvar "cmdecho" 0) (command "_.Undo" "group")
  (setq eob (entsel) lyr (cdr (assoc 8 (entget (car eob)))))
  (while eob
    (command "_.Extend" (ssget "x" (list (cons 8 lyr))) "" eob "")
    (setq eob (entsel)))
  (command "_.undo" "e") (princ)
)
Şeklini alır. bu fonksiyon geliştirilebilir elbette. mesela boundary olarak daima ilk objenin bulunduğu layer'daki objeleri ele alarak hepsinde aynısını kullanıyor, küçük bir değişiklikle, her seçilen objenin kendi layer'ındaki başka objelere kadar uzatılması sağlanabilir.

sizin de çözmeye çalıştığınız kontrollü ve sürekli obje seçerek işleme alma konusunda bir örnek olabilir diye düşünüyorum.
kolay gelsin.

ProhibiT (08.06.2011 19:00 GMT)

08.06.2011 19:55    

pitsss
Öncelikle ilgi ve alakandan dolayı teşekkür ederim prohibit. aslında ben autocad kullanmayı bilmiyorum. çizgi daire gibi basit çizimler yapabilirim ama. daha fazlasını yapamam. bu yüzden autocad de kullanılan çoğu komutu bilmiyorum. layer kontrolünü bilmiyorum. bunları zamanla öğreneceğim.
ilk yazdığım kodda kopyala yapıştır sistemi vardı. ancak ehya nın yardımıyla sonradan düzenlediğim kodda ise genelde hangi kodu niçin kullandığımı bilerek yaptım. umarım zamanla daha da başarılı olurum. sizlerin uyarılarıyla daha iyi olacağız inşallah.
mesela yazdığınız kodlar da bondary nedir (setvar "cmdecho" 0) (command "_.Undo" "group") nedir. bilmiyorum. ama birden hepsini öğrenebilirmiyim onu da bilmiyorum. zamanla uğraşılırsa herşey olur. eğer vaktim olur da autolisp i öğrenmeye devam edersem, sizlerden daha çok yardım talebinde bulunacağım. şimdiden teşekkürler :)

> 1 <
Copyright © 2004-2022 SQL: 1.122 saniye - Sorgu: 68 - Ortalama: 0.0165 saniye