İçeriğe atla
Yiğit Tenekeci
CV

Otomasyon

SAP GUI scripting: alan ID'lerini nasıl keşfederim?

Makroyu yazmak işin kolay tarafı. session.findById("wnd[0]/usr/ctxt...") satırının içine yazılacak o uzun metni bulana kadar geçen süre, makronun çalıştığı süreden uzun olabiliyor. Doğru ID’yi bir kere bulduysanız gerisi mekanik: alana yaz, düğmeye bas, Enter gönder. Bulamadıysanız script hiçbir şey yapmıyor — sadece “The control could not be found by id” hatası verip duruyor.

Bir alanın ID’sini bulmanın dört yolu var: kaydedici, F1 teknik bilgisi, obje ağacını dökmek ve doğrudan tıklayarak yakalamak. Hangisini kullanacağınız, ekranda neyi aradığınıza bağlı.

Kaydedici: script üreticisi değil, ID sözlüğü

SAP GUI’nin kendi kaydedicisi var: Alt+F12 → Script Recording and Playback. Kaydı başlatıyorsunuz, ne tıklarsanız VBScript’e çeviriyor. İlk makroda bu çıktıyı olduğu gibi kullandım, kötü bir fikirdi. Kaydedici sadece dokunduğunuz alanların ID’sini veriyor; masum saydığınız fazladan tıklamaları da script’e yazıyor ve araya sabit beklemeler koyuyor. Daha kötüsü, gezmediğiniz sekmenin, açmadığınız popup’ın alanları kayıtta hiç görünmüyor.

Kaydediciyi bırakmadım, kullanımını değiştirdim: ID sözlüğü olarak kullanıyorum, script üreticisi olarak değil. Kaydı başlatmadan önce akışı elle bir kere baştan sona geziyorum — hangi sekmeye girip hangi popup’ı açacaksam o ekranları açıyorum ki kayıt onları da görsün. Sonra kaydın içinden sadece ID satırlarını alıp kendi koduma taşıyorum. Kaydın geri kalanı çöp ama ID listesi altın değerinde.

F1: alanın gerçek adı

Dinamik ekranlarda (dynpro) daha okunaklı bir yol var. İmleci alanın içine koyup F1 → açılan performans asistanında Teknik Bilgi → pencerenin en altında “Ekran alanı” yazıyor. Örneğin RSYST-BNAME gibi bir isim. Bu isim, alanın ID’sindeki eleman adıyla eşleşiyor ve uzun ID yerine kullanılabiliyor:

session.findById("wnd[0]").findByName("RSYST-BNAME", "GuiTextField").Text = "KULLANICI"

Kısa, okunaklı ve konum bilgisi taşımadığı için daha dayanıklı. SAP ekranı yeniden düzenlediğinde uzun ID’deki txt[3,45] gibi koordinat kayar, alanın teknik adı yerinde kalır. Sınırı da var: findByName sadece dynpro alanlarında çalışıyor. Grid’lerde ve özel kontrollerde alanın böyle bir adı yok.

Obje ağacını dökmek

Her SAP ekranı bir ağaç ve ID’lerin mantığı bu ağacın kendisi. wnd[0] ana pencere, wnd[1] açılan popup, /usr kullanıcı alanı, tbar[0] araç çubuğu, sbar durum çubuğu, okcd komut alanı. Eleman tipleri de ID’nin başında yazıyor: txt metin kutusu, ctxt etiketli metin kutusu, btn düğme, chk onay kutusu, cmb liste, tab sekme, sub alt ekran, cntl özel kontrol. Grid’ler cntl.../shellcont/shell altında duruyor ve diğerlerine hiç benzemiyor.

Bu yapıyı bilince, hiç görmediğiniz bir ekran için 20 satırlık bir döküm script’i yazabiliyorsunuz: aktif pencereyi al, Children koleksiyonunda özyinelemeli gez, her elemanın Id, Type, Name ve Text değerini bir dosyaya yaz. Bir ID’yi bulamadığınızda kayıt almak yerine döküme bakıyorsunuz; dosyada ekranda ne varsa hepsi listeleniyor. Grid kolon adlarını aramak için de en pratik yol bu.

Tıklayarak yakalamak

Scripting’in kendi olay mekanizması da bu iş için kullanılabiliyor. Açık oturuma bağlanan küçük bir VBS dosyası, elementVisualizationMode = True yapıp session’ın Hit olayını dinlemeye başlıyor. Bundan sonra ekranda tıkladığınız her elemanın ID’si bir kutu içinde görünüyor — kopyalayıp script’e yapıştırıyorsunuz. Otuz satırlık bir dosya, ekran ekran gezip ID ezberlemekten çok daha hızlı. SAP’in kendi örnek araçları ve Scripting Tracker (Stefan Schnell’in ücretsiz aracı) da aynı işi yapıyor; hangisi elinizin altındaysa o yeter.

ID’lerin kırılgan tarafları

Birkaç tuzağa ilk makroda düştüm, sonrakilerde önceden biliyordum:

  • txt[3,45] gibi konum tabanlı ID’ler ekrana bir kolon eklendiğinde kayıyor. Mümkünse F1’den gelen alan adını kullanın.
  • wnd[1] yani popup: İşlem sırasında açılan bu pencereyi kontrol etmeden devam ederseniz script asıl ekrana değil popup’a yazmaya çalışıyor.
  • Grid’lerde satır ve sütun konumu yerine sütun adıyla okuyun; ekrana eklenen bir kolon aksi halde bütün eşleşmeyi kaydırıyor.
  • Birden fazla oturum açıksa Children(0) her zaman istediğiniz oturum olmayabilir. Hedef oturumu bağlantı ve sistem adından bulmak gerekiyor.
  • WebGUI (GUI for HTML) ve Fiori ekranlarında bu API yok. Yöntem SAP GUI for Windows’ta çalışıyor.
  • Scripting kapalıysa hiçbir yöntem işe yaramaz: SAP GUI seçeneklerinde izin verilmemiş ya da sunucudaki sapgui/user_scripting parametresi kapalıysa makro hiç başlamıyor. İlk kontrol edilecek şey bu.

Neyi farklı yapardım

İlk makroda ID’leri kodun ortasına dağıtmıştım. Bir ekran değiştiğinde düzeltilecek satırı aramak, hatayı bulmaktan uzun sürüyordu. Şimdi her makronun başında tek bir sabitler bloğu var; kullandığım bütün ID’ler orada duruyor. Ekran değiştiğinde tek satır düzeltiyorum, kodun geri kalanına dokunmuyorum.

Bir de ID avını ucuz bir iş sanmayın. Otomasyonun sıkıcı kısmı burası ama doğru ID olmadan en iyi mantık da çalışmıyor. Ben en çok zamanı session.findById satırlarını bulmakta harcadım. Bugün olsa ilk gün bir döküm script’i yazar, uğraştığım bütün ekranları tek bir metin dosyasında toplardım — bir kere yaz, her makroda kullan.