1C:Enterprise EĞİTİM
DERS 5
1C:Enterprise Ders 5-1
Uluslararası Kullanım
Küresel piyasada çalışan bir uygulama olarak biz çok dilli olmayı istiyoruz. Bazen yabancı müşterilerimize çözümleri kendi dillerinde sunmamız gerekiyor, Bazen de uluslararası bir ekibin aynı anda birkaç dilde çalışması gerekmektedir. Şimdi bunun 1C:Enterprise’da nasıl olacağını düşünelim.
Öncelikle, 1C:Enterprise’daki diller arasında 3 ana temel faktör vardır. Buna karşılık, 3 farklı dil kümesi arasında geçiş yapmanın 3 farklı yolu vardır.
En önemli kaynaklar (text strings) bir kullanıcıya görünür olanlardır. Onlar yukarıdaki tabloda kırmızı olarak boyanmıştır. Şimdi, konunun derinliklerine inelim.
1C kaynak kodu dili
1C kaynak kodu, geliştirici tarafından bazı modüller de kullanılır.
Geliştirici kaynak kodunu iki dilde yazılabilir: İngilizce (English) ve Rusça (Russian). Bunlar arasında geçiş yapmaya ihtiyacımız yok – sadece ihtiyacınız olan dilde ihtiyacınız olan kodu yazın. Aynı uygulama içerisinde iki dildeki kodları karıştırabilirsiniz ancak biz bunu kodu temiz ve rahatça anlaşılabilir olması açısından tavsiye etmiyoruz.
Unutmayın ki, bu listeye başka bir dil eklemenin hiçbir yolu yoktur.
Tasarımcı modunda Platform dili
Platform içinde Platform geliştiricileri tarafından kodlanmış bolca metin kaynakları vardır. Tasarımcı modunda herşey mevcut Platform dilinde gösterilir ve bu değiştirilemez. Aşağıda bu Platform kaynaklarının birkaç örneği vardır. (Kırmızı ile çizilenler). Yeşil ile özetlenen kaynaklar, uygulama kaynakları ve kaynakların dilleri geliştirici tarafından değiştirilebilir.
Konfigürasyon ağacı:
Platform kaynaklarından bir örnek daha, Tasarımcı tarafında gösterilen hata iletisi:
1C:Enterprise kullanıcı modunda Platform dili
Platform kullanıcı modunda birçok şeyi ifade eder.
Bunlar sistem formları, menüler, açıklamalar:
Sistem formları:
Sistem hata mesajları:
Ve daha fazlası.
Bunların hepsi mevcut Platform dilinde gösterilir.
Kullanılabilir Platform dilleri
Versiyon 8.3.5 için kullanılabilen tüm Platform dilleri aşağıda listelenmiştir. Not, Platform geliştirici sürekli olarak yeni diller ekleyebildikleri için gerçek bir liste için bu link i kontrol etmeyi unutmayın.
- – Azerbaijani
- – English
- – Bulgarian
- – Chinese
- – French
- – Georgian
- – Hungarian
- – Kazakh
- – Latvian
- – Lithuanian
- – German
- – Polish
- – Romanian
- – Russian
- – Turkish
- – Ukrainian
- – Vietnamese
1C:Enteroprise çözüm geliştiricisi bu yeni yeni bir dil ekleyemez ama Platform geliştiricileri ekleyebilir. Genellikle yeni diller, Platform geliştiricileri, 1C iş ortağı şirketlerinin ortak katkıları ile 1C LLC kaynak çevirisi üzerinden eklenir.
Platform dili değiştirme
Platformun birden çok dili desteklemesini istiyorsanız, kurulum aşamasında bu dilleri seçmelisiniz.
Kurulumdan sonra da Windows Denetim Masası’ndaki Yüklü Programlar listesindeki Değiştir komutu ile yeni diller yüklenebilir.
Dili yükledikten sonra komut satırında /L parametresi ile Platformun dilini değiştirebilirsiniz.
Şimdi nasıl çalıştığını görelim.
1C:Enterprise Ders 5-2
Uygulama dili
Biz bu derste uygulama dilini İngilizce (English) olarak geliştireceğiz. Bizim potansiyel bir müşterimiz var, yıldız gemileri onarım pazarında çalışan, uygulamayı alıp kendi dilinde kullanmak istiyor, biz bu durumda ne yapabiliriz- mesela Klingonca dili?
Tamam, hadi bunu yapalım.
Akla ilk gelen şey, uygulama içindeki tüm metin kaynaklarını klingonca dili analogları ile değiştirebiliriz. Bu yolla uygulamanın diğer bir sürümünü alabiliriz. Şimdiye kadar kulağa hoş geliyor. Ama biz ek işlevselliği yeni sürüm içinde kullanmak istiyoruz, bu durumda ne yapabiliriz? İki farklı uygulamaya sahibiz- English and Klingon. Yani, bizim tüm değişiklikleri her iki uygulama da yapmamız gerekmekte ve bu hem zaman kaybı olup hem de hata oluşması riskini arttırmaktadır.
Yani, uygulamayı direk olarak başka bir dile çevirmek kötü bir fikir. Uzun vadede işe yarayan tek şey, aynı uygulamayı string kaynakları ihtiyaç olan tüm dillerde içeren çok dilli bir uygulamaya çevirmektir.
Bunun 1C:Enterprise’da nasıl çalıştığını görelim.
İlk olarak konfigürasyon ağacındaki Genel sekmesinden Diller kısmına Klingonca dilini ekleyerek başlayalım.
Bundan sonra, kullanıcıya gösterilecek tüm string kaynakları için iki farklı dilde eşanlamlı kısmı olacaktır- English and Klingon. Şimdi bizim için tüm string kaynaklar için Klingonca eşanlamlı alanı eklemek mümkün olacaktır. Örneğin, şu an Müşteriler (Customers) kart listesi için Klingonca dilinde Çalışan (Employee) özniteliğine eşanlamlı kısmı eklemek mümkün olacaktır.
Çalışanlar (Employees) kart listesinin özelliklerini açıp, yeni dilde eşanlamlı açıklama ekleyelim:
Not, burada iki benzer alan vardır: Name and Synonym. Name alanını kart listesini kaynak kod yazarken çağırmak için kullanırız (Catalogs. Employees…). Synonym alanını ile Platform kullanıcı ara yüzünde kart listesini gösterirken kullanır. Yani şöyle diyebiliriz, Name alanını Tasarımcı modunda kaynak kod yazarken geliştirici kullanır ve görür, Synonym alanını ise kullanıcı modunda çalışırken kullanıcı görür. Bu iki alanın farklı değerlere sahip olduğunu söylemeye gerek yoktur.
Biz uygulama için ikinci bir dil ekliyoruz. Bunun nasıl olduğunu görelim:
Not, Eşanlamlı (Synonym) alanının yanında zoom ikonunun olduğunu unutmayın. Bu ikona tıkladığında açılan pencerede eklenen tüm dillerde Eşanlamlı tanımlanabilir. Bizim için şu an iki tane eşanlamlı giriş alanı vardır. Bu alanlar eklenen dillere göre herhangi bir sayıda olabilir.
Temelde, çeviri yapmak bundan ibarettir – biz her dil için kullanıcı ara yüzünde gösterilecek olan eşanlamlı alanını tanımlayabiliriz.
OK, biz ara yüzde kullanıcının konuştuğu dili gösteren bir uygulamayı nasıl yapacağız? Çok basit. Tek yapmamız gereken şey kullanıcı bilgi formunda bunu belirtmek.
Yani, bu kullanıcı her zaman uygulamayı çalıştırdığında ara yüzü Klingonca dilinde görecektir.
Bu işlemin nasıl olduğunu daha net görebilmek için Ana bölümdeki string kaynakları çevirerek görelim.
Uygulama mesajları
Uygulama string kaynakları kullanıcılara gösteren tek yer değildir. Kaynak kodu yazarken kullanıcının kullanacağı bir formda veya yapacağı bir işlem sırasında geliştirici gösterilmesi için string mesajlar kodlayabilir. Muhtemelen, bunun en yaygın örneği şudur:
MessageText = “Some message text”;
Message(MessageText);
Bu kod parçası çalıştığında uygulamada açıkça kodlanmış string mesajı içeren bir ileti kutusu gösterecektir.
Bu durumda bu string mesajı için eşanlamlı belirtebilir miyiz? Görelim.
Bu işlem için ortaya çıkan kod parçası şudur:
//6. divpare the error message and display it.
MessageText =
NStr(
“en = ‘There is not enough materials. See the list of deficits below:’;
|kl = ‘pa” ”oHbe” yap Hap ”u”. Hutlh tInwI” pagh tetlh vIlegh:'”
) + MessageText;
Bütün uygulamaya çeviri yapmak
Tüm uygulamaya çeviri yapmak için bizim şu nesnelerin hepsinin eklenen dil için Eşanlamlılarını (synonym) yazmamız gerekmektedir:
- – Tüm metadata nesneler dâhil olmak üzere:
- – Nesneler ve özniteliklerinin isimleri
- – Form elemanlarının isimleri
- – Kullanıcıya gösterilen tüm string kaynaklar
Gerçek hayatta kullanılan bir sistem için, bu neredeyse imkânsız bir hale gelebilir. Bunu hiçbir özniteliği atlamadan nasıl yapabiliriz? Kaynak kod içindeki tüm string kaynakları nasıl bulabiliriz? Neyse ki, Platform üzerinde bu sorunu kolaylıkla çözen basit ama güçlü bir araç vardır.
Biz bu menüyü seçtikten sonra, bir form açılacak.
İlk sekmedeki ayarları olduğu gibi bırakalım ve Modüller (Modules) sekmesine geçelim. Burada “Modüllerde “NStr” fonksiyonu ara (Search in NStr functions in modules)” onay kutusunun seçili olduğuna emin olalım.
Sonrasında biz “Bul (Find)” butonuna tıkladığımızda, Platform tüm uygulama içinde string kaynakları bulup, bize bir tablo içinde dökecektir.
İlk sütun, bize string kaynağın nereden alındığını gösterir. İkinci ve üçüncü sütunlar ise bu kaynakların İngilizce ve Klingonca versiyonları gösterir. Bazı kaynakların çevirisi zaten yapılmıştı. Kalan çevirilerde bu tablodan yapılacaktır.
Bu tablo için güzel bir şey var, direkt olarak çevrilmiş string kaynakları yerleştirebilirsiniz ve onlar hemen gerçek zamanlı olarak uygulamada olması yerlere kaydedileceklerdir.
Örnek olarak, Fiyatlar (Prices) IR’nin isminin tablo üzerinde çevirisini yapalım.
En kısa sürede IR de gerekli yerde çeviri hemen yapıldı ve kaydedildi.
Ayrıca bu tabloyu Excel vb. gibi uygulamalar için dışarı aktarıp, çevirileri doldurduktan sonra tekrar içeri aktarabilirsiniz.
Platform dili ve Uygulama dili
Dersin başlarına tekrar ir göz atın. Kırmızıya boyanmış iki hücre göreceksiniz. Bunun anlamı uygulamanın ara yüzünü istediğiniz herhangi bir dile çevirebileceğinizdir, ama her şey bununla bitmemektedir. Ara yüzün önemli bir bölümünde mevcut Platform dili gösterilmektedir. Bu yüzden, Platform tarafından desteklenmeyen bir dil için tam bir ana-dil çözümü sunulamaz.
Yeni diller sürekli olarak güncellenebildiği için şu linki kontrol etmeyi unutmayın: desteklenen diller listesi
Diğer araçlar
Bazı diğer araçlar uygulama kullanıcısına string mesaj gösterme yeteneğine sahiptir. Bunlardan iki tane önemli araç vardır: işletim sistemi ve DBMS (Veri tabanı Yönetim Sistemi) vardır.
Basit bir örnek verirsek, 1C:Enterprise içinde Windows’un seçim için açılabilen dialog penceresi. Diyelim ki, müşterilerin resimlerini infobase içinde saklamak istiyoruz. Bunu yapmak için Müşteriler (Customers) kart listesine Resim (Picture) adında bir öznitelik eklememiz ve bunun tipini ValueStorage olarak belirlememiz gerekir, böylece öğe formu üzerinde oluşan “Dosya Seç (Select File)” butonuna bastığımızda, Windows seçim dialog penceresi açılacaktır.
Notification = New NotifyDescription(“FileSelected”, ThisObject);
BeginPuttingFiles(Notification,,,True);
Kullanıcı bunu nasıl görür, bakalım;
Dosya seçimi penceresi Platform içinde açılmaz. Bunun yerine stanrdart Windows 8.1 penceresi çağrılır. Yani işletim sistemi tarafında oluşturan pencerenin dil bilgisi için 1C:Enterprise tarafından yapılacak bir şey yoktur.
Bazı zamanlarda 1C’nin başka uygulamalar ile iletişim kurduğunda ortaya çıkabilecek sorunlar olabilir. Eğer uygulama kodunda hata yakalama işleyicisi yoksa 1C hata mesajını olduğu gibi yakalayıp gösterecektir.
Aynı şey DBMS için de geçerlidir. Örneğin, iki tane 1C kullanıcısı aynı anda aynı parçaya veri yazmaya çalışırsa aşağıdaki gibi hata mesajı alınabilir.
İkinci satırdan itibaren bu hata mesajı SQL Server tarafından oluşturulur. 1C sadece bu hatayı kullanıcıya gösterir.
Eğer 1C kullanıcısının mevcut dili haricinde başka dilde bir şey görmek istemiyorsanız, şunlara ihtiyacınız vardır:
- – 1C Platformunun bu dili desteklemesi
- – Uygulamanın bu dile çevrilmiş olması
- – İşletim ve DBMS nin bu dilde çalıştırılması
1C:Enterprise Ders 5-3
Finansal varlıklar
Şirketimizin operasyonlarının asıl hedefi, şirket sahipleri için kâr elde etmektir. Kâr, gelirler-giderler olarak hesaplanır. Diğer bir deyişle, yeterli malzeme olup olmadığını bilmemiz gerekir. Çünkü ona göre ne kadar malzeme almamız gerektiğini hesaplayabiliriz. Malzeme fiyatlarını belirlerken de aynı sorun ortaya çıkar. Malzemenin bize ne kadara mal olduğunu bilmeliyiz ki, fiyatını belirlerken kâr oranını doğru hesaplayalım.
Biz birçok kez aynı malzemeden satın alabiliriz. Malzemenin fiyatı her seferinde farklı olabilir. Sonrasında da bu malzemeyi kâr elde etmek için satarız. Bunu yapabilmek için satış fiyatının alt sınırını yani maliyeti bilmek gerekir.
Bunu nasıl yapabiliriz, görelim. Bu tabloda bizim tüm depolarımız için uzatma kabloları bilgileri yer almaktadır.
Biz, temelde, bir uzatma kablosu sattığımız zaman, yığından rastgele bir örnek çekeriz. Yani bu yığın içerisindeki herhangi bir ürünü satmamız şans meselesi – 1 Eylül’de 1 dolara aldığımız malzeme de olabilir veya 13 Eylül’de 1,21 dolara aldığımız malzemede. Müşterinin bakış açısına göre tüm kablolar aynıdır, ama kâr etme payı açısından bizim için aynı olmayabilir. Eğer biz uzatma kablosunun tanesini 1,5 dolardan satmak istersek, malzemeyi aldığımız fiyata göre kârımız 0.4, 0.45 veya 0,29 dolar olabilir.
Aynı anda büyük miktarda bir sipariş geldiğinde bu iş daha da karmaşık bir hal almış olur. Şimdi, bizim elimizde 55 tane uzatma kablosu var ve 52 tanesini satmaya ihtiyacımız olursa ne yapacağız? Bu durumda toplam kârımızı nasıl hesaplarız?
Cevap olarak, bizim her malzemenin satın alma fiyatına ihtiyacımız yok. Biz “ne kadar malzeme kaldığı” problemini çözerken, bütün malzemelerin ne olursa olsun her belirli parçanın kaynağı yığınlar (her bir ambardaki her bir malzeme için bir yığın) içinde biriktiğini dikkate aldık.
Peki, biz her malzemenin maliyetini aynı kabul edersek ne olur? Biz sadece kalan malzemenin miktarlarını ve toplam fiyatları özetleyebiliriz ve bu bize ortalama birim fiyatı hesaplamak için bilgi verir (toplam fiyatlar / miktarlar).
Yani, biz uzatma kablosu sattığımızda her bir parçanın bize maliyetinin 1,16 dolar olduğunu tahmin ediyoruz. Tabii, bu ortalama maliyet, GoodsPurchase ve Services evrakları kaydedildiğinde değişecektir.
Bu adil bir yaklaşım mı? Biz gerçek kâr hesaplamasını ortalama maliyet üzerinden nasıl alacağız? Eh, genellikle öyle. 63,55 dolar – şu an elimizde olan malzemeler için toplam harcadığımız miktardır. Eğer biz bir ürünü 1,16 dolardan daha fazla bir fiyata satarsak, ürünün maliyeti 1,21 dolar bile olsa biz bu üründen kâr elde etmiş gibi görüneceğiz.
Bazı durumlarda satın alma belgesine satılan her malzemeyi bağlamak gerekebilir, ama şimdiki görevimiz için bu gerekli değildir.
Şimdi, biz malzeme maliyetlerini nasıl saklayabiliriz?
MaterialsCosts birikim kayıt tablosu (AR)
Biz daha önce BalanceOfMaterials AR’si oluşturmuştuk. Belki de bu nesneyi daha fazla kaynak ekleyerek maliyet saklamak amacıyla kullanabiliriz.
İşe yarayabilir ancak bu durumda farklı depolar için aynı malzeme maliyeti saklamış olacağız. Bu çözüm açıkçası çok gereksiz olur. Bizim için en iyi çözüm sadece Malzeme (Material) boyutu olan bir AR oluşturmaktır.
Kaynaklar (resources) olarak ne kullanacağız? Elimizde gerçekten ihtiyacımız olan gün sonu ortalama maliyet bilgisi var. Öte yandan, aynı malzemeden sürekli alıyoruz ve bu yüzden sürekli olarak ortalama maliyeti hesaplamak gerekir. Bunu yapmak için toplam maliyet ve toplam miktarı bilmek lazım. Biz kayıt anında miktar-maliyet bölmesi yaparak bunu hesaplayabiliriz ve gerçekten malzeme maliyeti bilgisine ihtiyacımız kalmaz.
Yani, yeni AR aşağıdaki yapıya sahip olacaktır.
Şimdi, bu AR’yi kullanıcı ara yüzünü görülebilir hale getirelim. Benim önerim “Para (Money)” adında bir alt sistem oluşturup o sistem altına eklemektir.
Yapmamız gerek bir sonraki şey GoodsReceipt evrakından bilgileri bu birikim kayıt tablosuna göndermek. Hareket yapılandırıcısını kullanarak BalanceOfMaterials evrakının kaynak koduna benzer bir kayıt kaynak kodunu oluşturabiliriz.
Sonuç olarak ihtiyacımız olan kaynak kod:
Procedure Posting(Cancel, Mode)
RegisterRecords.BalanceOfMaterials.Write = True;
RegisterRecords.MaterialsCost.Write = True;
For Each CurRowMaterials In Materials Do
// register BalanceOfMaterials Receipt
Record = RegisterRecords.BalanceOfMaterials.Add();
Record.RecordType = AccumulationRecordType.Receipt;
Record.Period = Date;
Record.Material = CurRowMaterials.Material;
Record.Warehouse = Warehouse;
Record.Quantity = CurRowMaterials.Quantity;
// register MaterialsCost Receipt
Record = RegisterRecords.MaterialsCost.Add();
Record.RecordType = AccumulationRecordType.Receipt;
Record.Period = Date;
Record.Material = CurRowMaterials.Material;
Record.Quantity = CurRowMaterials.Quantity;
Record.Cost = CurRowMaterials.Price * CurRowMaterials.Quantity;
EndDo;
EndProcedure
O halde, önceden kaydedilmiş verileri kayıt altına almak için GoodsReceipt evraklarını tekrar kaydetmek gerekir. Bittiğinde, yeni AR tablosu aşağıdaki alanları içerir. (Sorgu yapılandırıcısı aracılığıyla görebilirsiniz).
QuantityBalance kalan malzemelerin toplam miktarını ve CostBalance ise bu malzemeler için ödenen toplam ücreti içerir. CostBalance değerini QuantityBalance değerine bölersek geçerli malzeme için fiyatı alabiliriz. Not, biz MaterialsCost.Balance sanal tablosunun parametlerini kullanarak herhangi bir zaman için bu değeri alabiliriz.
SELECT
Cost.CostBalance / Cost.QuantityBalance AS ItemCost
FROM
AccumulationRegister.MaterialsCost.Balance(&Date, ) AS Cost
Şimdi, biz malzemenin maliyetini hesapladığımızda, malzemeyi yeniden fiyatlandırmayı ya da malzemenin satılmasını önerebiliriz.
1C:Enterprise Ders 5-4
Yeniden maliyetlendirme
Şimdi malzemeleri yeniden fiyatlandırma için doğru arama yapan bir kullanıcıya yardımcı olma fırsatımız var. Biz herhangi bir zaman anında geçerli malzemenin fiyatının ne olduğunu biliyoruz, yani bir kullanıcı tarafından belirlenen fiyatın kârlı olup olmadığını belirleyebiliriz.
Tabloya yeni bir sütun ekleyip ve belgenin tarihi ile eş olan malzeme maliyetleri ile dolduralım. Ayrıca, kullanıcının belirlediği fiyat, malzemenin maliyetinden az ise bunu kontrol edip, kullanıcıya fiyatı düzeltmesi için bir uyarı ve şans verebiliriz.
Hadi bunu yapalım.
PriceChange evrakının modülü ve kaynak kodunun son hali:
&AtServer
Procedure OnCreateAtServer(Cancel, StandardProcessing)
RecalcCosts();
EndProcedure
&AtServer
Procedure RecalcCosts()
For Each Material In Object.MaterialsAndServices Do
Material.Cost = GetCurrentCost(Material.MaterialOrService, Object.Date)
EndDo;
EndProcedure
&AtServer
Function GetCurrentCost(Material, Date)
//Exclude services
If Material.MaterialOrService = Enums.MaterialOrService.Service Then
Return 0;
EndIf;
//Get the cost for the date of the document
Query = New Query;
Query.Text =
“SELECT
| MaterialsCostBalance.CostBalance AS TotalCost,
| MaterialsCostBalance.QuantityBalance AS Quantity
|FROM
| AccumulationRegister.MaterialsCost.Balance(&Date,
| Material = &Material) AS MaterialsCostBalance”;
Query.SetParameter(“Date”, Date);
Query.SetParameter(“Material”, Material);
QueryResult = Query.Execute();
SelectionDetailRecords = QueryResult.Select();
If SelectionDetailRecords.Next() then
If SelectionDetailRecords.Quantity > 0 Then
Return(SelectionDetailRecords.TotalCost / SelectionDetailRecords.Quantity);
EndIf;
EndIf;
Return 0;
EndFunction
&AtClient
Procedure MaterialsAndServicesMaterialOrServiceOnChange(Item)
Item.Parent.CurrentData.Cost =
GetCurrentCost(Item.Parent.CurrentData.MaterialOrService, Object.Date);
EndProcedure
&AtClient
Procedure DateOnChange(Item)
RecalcCosts();
EndProcedure
Services evrakının MaterialsCost AR’sine kayıt yapması
MaterialsCost AR’sini depo bakiyelerinin finansal temsili olarak düşünebiliriz. BalanceOfMaterials AR’si ile kayıt yaparken ne kadar malzeme kaldığını, MaterialCost AR’si ile kayıt yaparken de bu kalan malzemeler için ne kadar ücret ödediğimizi biliyoruz. Diğer bir değişle, depolarımızda ne kadar satılabilir malzeme kaldığını biliyoruz.
Biz ne zaman yeni bir malzeme satın alırsak (yeni GoodsReceipt evrakı ile kayıt), bu malzemenin fiyatını MaterialsCost AR tablosuna ekliyoruz. Aynı şekilde biz ne zaman bir satış yaparsak Services evrakı ile bu malzemenin fiyatını MaterialsCost AR tablosundan çıkartıyoruz.
Bu belgenin kaydedilmesi elbette malzemenin maliyetini etkiler. Eğer biz şu anki malzeme maliyetinden daha az maliyeti olan bir malzeme satarsak, biz ortalama maliyeti arttırıyoruz. Eğer biz daha pahalı bir malzeme satarsak, bu sefer azaltmış oluruz. Şimdi bunu daha iyi anlamak için görselleştirelim. Bu tablo belli bir süre içinde bir malzemenin alış ve satış sürecini gösteriyor.
T1 ve T3 anı arasında malzeme fiyatı sürekli yükseliyor ve biz 30 tane malzeme satın alıyoruz. (1 dolardan 2 dolara). Bu periyod sonunda, ortalama maliyet 1,5 dolar oldu. T4 anında, biz kötü bir seçim yaparak 20 ürünü 1 dolardan sattık (maliyetten malzeme başı 0,5 dolar az). Bu madde maliyetinin birden 2,5 dolara çıkmasına sebep oldu. Biz bu durumda bu olaydan sorumlu olan satış elemanını görevden alabiliriz ve fiyatı arttırabiliriz. Sonrasında biz 5 adet ürünü 4 dolardan sattık ve ortalama maliyet tekrar 1 dolar seviyesine geri geldi. Bu işlemden sonra birden fazla 5 dolardan ürün satarsak ortalama maliyet 0 dolar olacak ve sonraki satışta 2 tane ürünü 3 dolardan satınca maliyet-2,5 dolar olacaktır, bunun anlamı şu an ürün ücretsiz bile satılsa kâr elde edilebilir.
Şimdi bu yazdıklarımızı yapmak için birkaç değişiklik yapmalıyız. Platform’a Services evrakında kaydedilen kayıtları MaterialsCost AR’sine kaydetmesini söyleyelim.
Evrağın kaynak kodunda ihtiyacımız olan değişiklik (burada kodun sadece ilk kısmını veriyoruz).
Procedure Posting(Cancel, Mode)
// 1. Filling out the registers’ recordsets
For Each CurRowMaterialsAndServices In MaterialsAndServices Do
RegisterRecords.BalanceOfMaterials.Write = True;
RegisterRecords.MaterialsCost.Write = True;
If CurRowMaterialsAndServices.MaterialOrService.MaterialOrService <>
Enums.MaterialOrService.Service Then
// 1.1. Filling out BalanceOfMaterials recordset
Record = RegisterRecords.BalanceOfMaterials.Add();
Record.RecordType = AccumulationRecordType.Expense;
Record.Period = Date;
Record.Material = CurRowMaterialsAndServices.MaterialOrService;
Record.Warehouse = CurRowMaterialsAndServices.Warehouse;
Record.Quantity = CurRowMaterialsAndServices.Quantity;
// 1.2. Filling out MaterialsCost recordset
Record = RegisterRecords.MaterialsCost.Add();
Record.RecordType = AccumulationRecordType.Expense;
Record.Period = Date;
Record.Material = CurRowMaterialsAndServices.MaterialOrService;
Record.Quantity = CurRowMaterialsAndServices.Quantity;
Record.Cost = CurRowMaterialsAndServices.Quantity * CurRowMaterialsAndServices.Price;
EndIf;
EndDo;
Bundan sonra, daha işlevsel işlemler yapalım. Sonuçları kontrol etmek için, tüm Services evraklarını tekrar kaydetmek ve MaterialCost AR’sine bakmak gerekir. Satılan tüm malzemeler kırmızı işaret ile işaretlenmiş şekilde gösterilir.
Satış Malzemeleri Asistanı
Bir kullanıcı Services evrakını doldurduğu zaman mevcut malzeme veya hizmetin fiyatları bilgi kayıt sisteminden elde edilir. En kısa zamanda güncellenen fiyat prosedürü uyguladığımız için bu fiyatlar anlamlı olacaktır. Ama kullanıcı hala bu varsayılan fiyatı değiştirebilir ve kasıtsız bir hata oluşabilir.
Biz bu fiyatı salt okunur yapabiliriz, bu sayede kullanıcının fiyatı değiştirmesine engel olabiliriz ama önemli bir işlevselliği de yitirmiş oluruz. Bir standart fiyat tüm durumlar için geçerli olabilir ve bazen sadece kullanıcının değiştirmesi gerekir. Eğer satış fiyatı ortalama maliyetten az olursa bizim sadece bir kullanıcıya uyarı göstermemiz gerekir. Bu uyarı kullanıcının daha bilinçli karar vermesine izin verir. Şimdi, biz aynı işlevselliği Services evrakındaki tüm malzemelere uygulayalım.
GetCurrentCost fonksiyonunu PriceChange evrakında kullandık bu Services evrakında kullanmaktan daha iyi bir seçim oldu, yani ortak modüle taşıyalım.
Server ve Server call onay kutularının seçili olduğuna emin olun. Modüller, prosedürler ve fonksiyonlar ilk olarak sunucu tarafında çalışacak ve istemci tarafından çağırılacak anlamına gelir.
Fonksiyon modülünün sonuna “Export” kelimesini tanımlıyoruz. Ders 2’den hatırladığımız gibi, bu kelime fonksiyon veya prosedürün modül dışından çağırılabilmesine izin verir.
Function GetCurrentCost(Material, Date) Export
Daha sonra Services evrakında PriceChange evrakındaki değişiklikleri uygulayın:
- – Yeni bir tablo sekmesi özniteliği ekleyin ve tipini Number olarak ve salt okunur olarak belirleyin;
- – Form için aynı koşullu görünümü ugulayın;
- – OnCreateOnServer ve MaterialsAndServicesMaterialOrServiceOnChange olay işleyicileri ekleyin;
- – Yeni DateOnChange olay işleyicisi oluşturmak. Tüm formlarda değiştirilecek işlemler bunlar.
Gerekli tüm değişiklikler ile birlikte form modülünün tamamı:
&AtClient
Procedure MaterialsAndServicesQuantityOnChange(Item)
Material = Item.Parent.CurrentData;
Material.Total = Material.Price * Material.Quantity;
EndProcedure
&AtServer
Procedure OnCreateAtServer(Cancel, StandardProcessing)
For Each Material In Object.MaterialsAndServices Do
Material.Total = Material.Price * Material.Quantity;
Material.Cost = GeneralPurpose.GetCurrentCost(Material.MaterialOrService, Object.Date)
EndDo;
EndProcedure
&AtClient
Procedure MaterialsAndServicesMaterialOrServiceOnChange(Item)
Item.Parent.CurrentData.Price =
GetCurrentPrice(Object.Date, Item.Parent.CurrentData.MaterialOrService);
Item.Parent.CurrentData.Cost =
GeneralPurpose.GetCurrentCost(Item.Parent.CurrentData.MaterialOrService,
Object.Date);
EndProcedure
&AtServer
Function GetCurrentPrice(Date, Ref)
Filter = New Structure;
Filter.Insert(“MaterialOrService”, Ref);
CurrentPrice = InformationRegisters.Prices.GetLast(Date, Filter);
Return CurrentPrice.Price;
EndFunction
&AtClient
Procedure DateOnChange(Item)
RecalcCost();
EndProcedure
&AtServer
Procedure RecalcCost()
For Each Material In Object.MaterialsAndServices Do
Material.Cost = GeneralPurpose.GetCurrentCost(Material.MaterialOrService, Object.Date)
EndDo;
EndProcedure
1C:Enterprise Ders 5-5
Malzeme dinamik maliyet analizi
Bu derste de daha önce tartıştığımız gibi malzemenin maliyetinin ne olduğunu ve nereye kadar malzemenin satış fiyatını arttırmamız gerektiği anlamına gelir. Aksi takdirde, kârımız düşüyor. Ve tam tersi – ne zaman malzemenin maliyeti aşağı inerse kârımız artar. Yani, malzemenin dinamik maliyet değişiklikleri bizim küçük işletmemiz için doğru fiyatı bulmak için birçok şey ifade ediyor.
Bu nedenle şirketimizde bu işlevi uygulamak için yeni bir görev ayarlayalım – tüm malzemeler için günlük dinamik maliyetleri almak.
Zaten ihtiyacımız olan veriyi saklamak için AR içinde yerimiz var- MaterialCost. İki kaynak vardır – Miktar (Quantity) ve Maliyet (Cost), yani, eğer biz herhangi bir gün için kaynakları alırsak ve maliyeti miktara bölersek o gün için dinamik maliyeti bulabiliriz. Ortaya çıkan tablo şu şekilde olmalıdır:
Bu tablo günlük olarak Malzeme maliyet değişimlerini içerir. Öğe maliyeti sütun değerleri Maliyet / Miktar işlemi yapılarak hesaplanır. Not, bazı günler malzeme alım veya satımı olmaz ve bu nedenle, bu günler malzeme miktar ve maliyetinde değişiklik olmaz. Öte yandan, bazı günlerde bir malzeme birden fazla işlem içerebilir. Bu durumda, genel olarak bakiye değişimi özetlenerek gösterilecektir.
Tablo şeklinde veri pek anlamlı görünmüyor, ancak diyagram görünümünü kullanabiliriz.
Bakalım bu tablo ile neler yapabileceğiz.
Biz zaten birikim kayıt bakiye tablosu kullanmayı biliyoruz, ama neredeyse belirli çözümler için iyi bir seçimdir. Eğer sorgu yapılandırıcısını çalıştırırsanız ve MaterialsCostBalance tablosunu açarsanız yalnızca tarih parametresinin ayarlanabilir olduğunu göreceksiniz, bu yüzden gün gün tablo içinde sorgulama yapmak gerekir (performans açısından oldukça kötü bir fikir).
Sorgu Yapılandırıcısındaki diğer MaterialsCost-related tablolarına göz atalım.
Her iki tablo parametrelerine göz atarak, ihtiyacımız olan her şeyi alabiliriz. Biz dönem sınırları ayarlarını ikinci yıl için ayarlanabilir parametre ayarlarını görüyoruz
BalanceAndTurnovers sanal tablosu içinden veri almak için iyi bir fikir, içeriği basit bir rapor haline getirelim.
BalanceAndTurnovers sanal tablosu. Düz liste raporu.
Tamam, şimdi BalanceAndTurnovers sanal tablosunun içeriğini görelim.
Seçili alan uzatma kablosunun günlük alış ve satış geçmişini yansıtıyor. İlk satır, ilk durum ve ilk işlemi gösterir. Maliyet ve Miktar bakiyesi başlangıçta sıfırdır. Şimdiye kadar gider yok, yani hiç harcama yok, ama 100 kablonun toplam maliyeti 1500 dolar. Bu iki sayı alınan malın karşılığı ve bu karşılığa gelen miktarı gösterir.
Devir hesaplama formülü Toplam(Receipts)- Toplam(Expenses) olarak hesaplanır. Diğer bir deyişle, devir, verilen süre boyunca bakiye değişikliğini yansıtır (bu durumda günlük). Dönem başında bazı kaynak bakiyesi vardır, sonra biz daha fazlasını ekledik (malzeme satın aldık) ve bazılarını azalttık (malzeme sattık). Sonuç olarak bu dönem için kapanış bakiyesi vardır. Yani, bu iki formül devir terimini açıklar ve başlangıç ve dönem sonu bakiyesi için bağlantıdır.
Turnover = Sum(Receipts) – Sum(Expenses) Devir = Toplam(Receipts) – Toplam(Expenses)
Ending balance = Starting balance + Turnover Kapanış bakiyesi = Başlangıç bakiyesi + Devir
Bu nedenle, birinci satır (2015-03-27) devir maliyeti 1,500 (= 1,500 – 0) ve bugün için kapanış bakiyesi 1,500 (= 0 + 1,500). İlk satır devir miktarı 100 (= 100 – 0) ve kapanış bakiyesi 100 (= 0 + 100).
Bir sonraki önemli (basit) formül şudur:
Kapanış bakiyesi (son dönem) = başlangıç bakiyesi (mevcut dönem)
Bu nedenle, ikinci satırın (2015-09-01) başlangıç bakiyesi birinci satırın kapanış bakiyesine eşittir. Bugün 51 tane kablo toplam 805 dolara satıldı, yani kapanış bakiyesi 695 (1,500- 805) ve miktarın kapanış bakiyesi 49 (100- 51) oldu.
Bizim önceki görevimize dönersek (Malzemelerin maliyetlerinin dinamik izlenmesi): ihtiyacımız olan her şeye BalanceAndTurnovers tablosunda sahibiz, yani rapor çıktımızda kullanmak için tabloya çeki düzen vermemiz gerekiyor.
Geçerli rapor için düzeltilmesini istediğim şeylerin listesi:
- – Görsel olarak farklı malzemeler birbirinden ayrı;
- – Dönem sütununu doğru girmek: formatı şuna değiştirmek YYYY-MM-DD ve böylece zamandan tasarruf etmek;
- – Başlangıç bakiyesi, irsaliye, fatura ve akış sütunları hariç. Miktar ve Maliyetin Kapanış bakiyesi sütununu yeniden adlandıralım;
- – Yeni sütun ekleyelim Öğe Maliyeti = Maliyet / Miktar.
Raporun toparlanması
Yani, bu şimdi var olan rapordur.
Malzeme hiç olmadığı zamanlarda ekranda “division by zero” hata mesajı görünmektedir, yani malzeme maliyet hesaplanamaz. Bu durumda biz 0 çıktısı verelim. Ama bunu nasıl yapacağız?
Tamam, olay şu. ItemCost ifade değerini hesaplamak için kullandık, Belli ki bir Rapor Oluşturucu tarafından yorumladığı string ifadeyi içerir. Burada alan adları ve bölme işlemi için kullanılan ifadenin sözdizimi yazımı nasıldır (sorgu)?
Eğer 1C: Enterprise 8.3 Developer Guide bakıyorsanız şurada bulabilirsiniz- 10.3.4. Veri kompozisyon sistemi ifade dili – ihtiyacımız olan referansları içeren. Bizim amaçlarımız için kullanabileceğimiz operatör CASE dir.
Bu nasıl çalışır.
Temelde, seçim koşulları kümesi karşı giriş değerini denetler ve gerçekleşen ilk koşul da çıkış değerini döndürür. Bu durumda, şu ifadeyi kullanabiliriz:
CASE
WHEN QuantityClosingBalance <> 0 THEN CostClosingBalance / QuantityClosingBalance
ELSE 0
END
Düzeltmelerden sonra, rapor şöyle gözüküyor.
DCS (Veri inşa edilme şeması) kaynakları
Eğer ağacın tüm ilk birimlerini daraltırsak, rapor tamamen bilgi veremez hale gelir.
Malzeme isimleri görüyoruz ancak başka hiçbir şey yok. Şimdi, görünümü kullanıcı için daha kullanışlı hale getirelim. Örneğin, burada mevcut bütün alanlar için bilinen son değerleri göstermek, çok iyi olurdu. Ama bunu nasıl yapabiliriz?
Bu grupları veri elde edilemez olarak kullanıyoruz, bunu değiştirelim (sadece ayrıntılı kayıtları içerir), ama bunu DCS için nasıl hesaplatabiliriz. Bunu yapmak için grupları kaynak olarak belirtmek ve hesaplama ifadeleri belirtmek gerekir. Kaynaklar – DCS tarafından veri kümesinden alınan ve zaman içinde hesaplama yapmak için kullanılan numeric değerlerdir.
Yani, DCS’yi açalım ve Kaynaklar sekmesine geçelim. Formda gerekli alanları sağ tarafa sürükle bırak yöntemi ile taşımalıyız. DCS otomatik olarak Sum () hesaplama ifadesini belirtir.
İlk olarak, deneme raporu alarak yaptığımız değişiklik nasıl göründüğüne bakalım. İstediğimiz gibi olup olmadığına bakalım.
Şaşırtıcı bir şekilde tam istediğimiz şeyi Maliyet ve Miktar toplamlarını gösterdi – toplama işlevini kullanıyor olmamıza rağmen bilinen son değerleri gösterdi. Diğer yandan, malzeme maliyeti ayrıntılı bir şekilde toplam kayıtları gösterir, ihtiyacımız olan şey değil ama en azından, hesaplama formülü ile uyumludur. Tamam, hepsi için nasıl çalışır?
Herhangi bir veri seti herhangi bir role aittir (roller, kullanıcı hakları ile karıştırılmamalıdır). DCS alan Rolleri DCS işlemcisi tarafından rolün alanları değiştirebileceği şekilde tanımlanır. DCS otomatik olarak veri kümesinden alacağı alanları tanır ve Rolleri belirtir (eğer otomatik onay kutusu seçilirse).
Maliyet ve Miktar Kapanış bakiyesi alanları “Bakiye” rolüne sahip ve bakiye türü “Kapanış bakiyesi”.
DCS, bu alanları içeren bir veri yapısı için ipucu verir. DCS bilinen son ayrıntılı kayıtları almak yerine onların özetlerini alması gerektiğini nasıl biliyor. Diğer bir değişle, Sum operatörü en alt satırdaki değeri verir, alanın rolüne göre herhangi bir miktar ya da değer bilinen son değer olabilir.
Yani, biz CostClosingBalance ve QuantityClosingBalance kaynakları ifadelerini olduğu gibi bırakalım.
Şimdi, ItemCost kaynak ifadesine başvurulabilir. Burada kesinlikle bağımlı kayıtları özetlemeye ihtiyacımız yok. İhtiyacımız olan şey Sum(CostClosingBalance) / Sum(QuantityClosingBalance). Toplam(Sum) operatörü bize bilinen son değeri verir, başka bir bölme işlemi ve öğe maliyetinin son bilinen değeri. Bunun yanı sıra, daha önce tartıştığımız “division by zero” ifadesini dikkate almak gerekir. Yani, ItemCost kaynağı için son ifade şöyle olacaktır.
CASE
WHEN Sum(QuantityClosingBalance) <> 0
THEN Sum(CostClosingBalance) / Sum(QuantityClosingBalance)
ELSE 0
END
Ayrıca, biçimlendirme sorununu çözmek için ItemCost hesaplanan değeri için tür belirtmeliyiz (Number (15, 2)).
Raporun son haline göz atalım:
Şimdi, daha sezgisel olarak anı veriyi belli bir diyagram şeklinde temsil ederek raporu ifade edelim. Ayrıca bu, kullanıcı özel bir dönem için verileri görmek istediğinde daha kullanışlı ve yardımcı olacaktır.
Rapora diyagram ekleme
Şimdi elimizde tüm Malzemeler için birim maliyet değişikliklerinin geçmişini gösteren bir tablo ve diyagram içeren bir rapor var.