Veri Analizi ve Raporlama Modülü

V

VBA|Uygulama|Proje

Odak: Veri Analizi, Raporlama Otomasyonu, Şablon Tabanlı Belge Üretimi
Kapsam: Kurumsal ortamlarda Excel–Word entegrasyonu ile veri işleme, analiz ve otomatik raporlama

Açıklama:
Bu çalışma, TCMB bünyesinde geliştirilen bir modülün sadeleştirilmiş ve anonimleştirilmiş versiyonudur. Modül, Excel verilerini doğrulayıp işleyerek analiz sonuçlarını Word şablonları üzerinden otomatik raporlara dönüştürür. Manuel veri hazırlama ve rapor oluşturma süreçlerini ortadan kaldırarak daha hızlı, tutarlı ve standart çıktı üretimini sağlar.


Bu makalede Word dosyasında hazırlanan/sunulan sıkı biçimsel özelliklere sahip detaylı bir raporun, VBA ile nasıl otomatize edildiğinden bahsedilecektir. Sıkı biçimsel özelliklerle birlikte çok sayıda grafik, tablo, metin, dipnot, açıklama vb. içeriğe sahip, belirli periyotlarda hazırlanan uzun raporlarınız için oldukça kullanışlı olacağını düşünüyorum. Hazırlanması günler ya da haftalar süren raporlar, VBA kullanılarak saniyeler içinde standardize bir şekilde oluşturulabilir. Ayrıca otomatik olarak hazırlanan raporu farklı kaydetmek suretiyle, raporun üzerinde manuel olarak değişiklikler, ekleme ve/veya çıkarmalar yapabileceğiniz esnekliğe de sahip olacaksınız.

Makalede örnek uygulama olarak temsili bir iş süreci için Excel’de hazırladığım “Raporlama Modülü” isimli uygulama kullanılacaktır. “Raporlama Modülü”nü GitHub platformu üzerinden buradan indirebilirsiniz. Raporlama Modülü 64 bit mimariye sahip Windows 7 ve üzeri işletim sistemlerinde, 2010 ve üzeri 32/64 bit Microsoft Office sürümlerinin tümünde çalışacak şekilde tasarlanmıştır. Modül, Windows’un daha eski sürümlerinde, MAC, Linux gibi farklı işletim sistemlerinde ya da MS Office’in önceki sürümlerinde test edilmemiştir.

Modülün çalışabilmesi için xlsm uzantılı Raporlama App isimli Excel dosyası ile ModuleFiles isimli klasörün aynı dizinde bulunması gerekir. Örneğin “Raporlama Modülü” isminde bir klasörümüz varsa, xlsm uzantılı Raporlama App isimli Excel dosyası ile ModuleFiles isimli klasör “Raporlama Modülü” isimli klasörün içinde yer almalıdır.

Modül Türkçe dışındaki dillerle de herhangi bir ayar yapmadan çalışacak şekilde tasarlanmıştır. Bu sebeple modülde yer alan bazı kritik isimlendirmelerde Türkçe-İngilizce ifadeler bir arada kullanılmıştır. Eğer modülün çalışmasıyla ilgili karakter probleminden kaynaklı bir sorun ile karşılaşılırsa, Ayarlar, Yönetici dil ayarları, Yönetimsel (Sekmesi), Sistem Yerel Ayarını Değiştir, Türkçe (Türkiye) yolunu izleyip bilgisayarı yeniden başlatınız. Yapılan ayar işletim sistemi (Windows arayüzü) dilinde herhangi bir değişiklik meydana getirmez. Sadece Türkçe karakterlerden oluşan bir uygulamada Türkçe karakterlerin düzgün görüntülenmesini/ bu modül özelinde ise Türkçe karakterlerin düzgün görüntülenmesine ilave olarak klasör ve dosya dizinlerinin doğru bir şekilde bulunmasına, modülün beklendiği şekilde çalışmasına olanak tanır.

Modülü kendi iş süreçlerinize/raporlarınıza uyarlamak için modülün algoritmalarında değişiklik yapmanız gerekebilir. Modülü uyarlamak için ihtiyaç duyabileceğiniz güvenlik şifrelerinin tümü (başında ve sonunda denden işareti olmadan) “123”tür.

Excel Can’t Find Project or Library Hatası Çözümü

Proje dosyasını açtığınızda, MS Office sürümleri arasındaki farklardan dolayı Excel Can’t Find Project or Library şeklinde bir problem ile karşılaşırsanız, çözüm için aşağıdaki videoyu inceleyebilirsiniz.

1.  Giriş

Yukarıda GitHub üzerinden rar/zip formatında indireceğiniz dosyayı bir klasöre çıkartınız. Çünkü modül rar/zip dosyası içinde çalışmayacaktır. Sıkıştırılmış rar/zip dosyasından çıkarttığınız klasörün içinde “ModuleFiles” isimli bir klasör ve “Raporlama App” isimli xlsm uzantılı bir Excel dosyası göreceksiniz. İleri seviyede VBA bilenler modülü kendi iş süreçlerine uyarlamak için “ModuleFiles” isimli klasörün içindeki bazı dosyaların içeriklerini yeniden yapılandırması gerekecektir. Ancak modülün temel çalışma ilkelerini anlamak ve onu tanıtmak veya kullanmak için “Raporlama App” isimli Excel dosyasının çalıştırılması/açılması yeterli olacaktır. “Raporlama App” dosyası açıldığında (ribbonun hemen altında, çalışma sayfasının en üstünde) sarı bir şerit üzerinde “İçeriği Etkinleştir/Enabled Content” gibi bir ifade ile karşılaşılırsa, “İçeriği Etkinleştir/Enabled Content” ifadesine tıklanıp (eğer ikinci bir pencere açılırsa ona) onay verilmesi yeterlidir.

Açılan dosyada “Raporlama Modülü” isimli sekmeyi tıkladığınızda aşağıdaki gibi bir ekran/menü ile karşılaşacaksınız. Verilerin kullanıcı tarafından modüle manuel olarak girileceği veya başka bir kaynaktan copy-paste edeceği varsayılmıştır. Veri girişleri “Veri Girişi Grubu” altında toplanan X Verileri, Y1 Verileri, Y2 Verileri vb. ikonlardan/sayfalardan oluşmaktadır.

“Raporlama Grubu” altında ise sadece “Raporlama Arayüzü” isimli ikon vardır. Güncel verilerinizi modüle girdikten sonra (ya da modüle daha önceden girilen eski veriler varsa) “Raporlama Arayüzü”ne tıklayınız ve açılan formdan raporlama dönemini seçip “Raporla” butonuna tıklayınız.

Raporun içereceği veri aralığının başlangıç ve bitiş tarihlerini açılır listelerden seçiniz. Açılır liste üzerinde çift tıklarsanız veya açılır listenin sağındaki aşağı yönlü oku tıklarsanız dönemler görüntülenecektir. Başlangıç ve bitiş tarihlerine ilişkin açılır listelerin değerleri (yani dönemler) veri girişlerinize göre otomatik olarak güncellenir. Raporla butonuna tıkladığınızda aşağıda gösterildiği gibi raporunuz bir Word dosyasında otomatik olarak hazırlanır. Word dosyası ekranda otomatik olarak görüntülenmediyse, altta görev çubuğunuz üzerinde turuncu renkli yanıp sönen Word ikonuna tıklamanız yeterlidir.

Modülün hazırladığı raporda yapacağınız manuel değişiklikleri modülün hazırladığı Word dosyası üzerinde kaydedemezsiniz. Bu yüzden modül tarafından yukarıda hazırlanan raporu, aşağıdaki ekran görüntüsünde işaret edildiği gibi Save As (Farklı Kaydet) yolunu izleyerek “Word Belgesi/Word Document” olarak kaydetmeniz gerektiğini unutmayın!

Yukarıdaki 3. adıma, yani kayıt türü kısmında “Word Belgesi/Word Document”i seçtiğinize dikkat edin. Kaydet butonuna tıkladığınızda aşağıdaki gibi bir uyarı mesajı çıkacaktır. Buna basitçe “Evet” demeniz yeterlidir.

Yukarıdaki adımlara izleyerek masaüstünüze kaydettiğiniz (yani modülün dışına aktardığınız) raporunuz üzerinde dilediğiniz değişikliği yapabilirsiniz.

Ribbon’da yer alan “Masaüstü Kısayolu” ikonuna tıkladığınızda, masaüstünüzde modülü çalıştırdığınız klasörde bulunan “Raporlama App” isimli Excel dosyasına bir kısayol oluşturulur. Söz konusu ikonu masaüstünüzden dilediğiniz zaman silebilirsiniz. “Masaüstü Kısayolu” ikonuna tekrar tekrar tıklamak, masasütünüzde çok sayıda kısayolun oluşmasına yol açmaz, sadece var olan kısayolu günceller.

“Yardım” ikonuna tıklarsanız da aşağıdaki gibi modüle ilişkin temel bilgileri içeren bir yardım penceresi açılır.

2.  Modülün İş Analizi ve Kurgusu

Modül, kurgusal bir iş sürecine ilişkin verileri dönüştürüp raporlamaktadır. Modülün kurgusunda fiyatları 80, 70, 60, 50, 40 ve 30 TL olan altı adet ürünü, X firmasının yurt içinde ve yurt dışında sattığı varsayılmıştır. Y firmasının Y1 ve Y2 adında iki şubesi olduğu ve Y firmasının şubeleri aracılığıyla X firmasının ürünlerini (X firmasının fiyatından) yurt içine ve yurt dışına sattığı varsayılmıştır. Y firması, sattığı ürünleri X firmasından veya (X firmasının izin verdiği) Z firmasından tedarik etmektedir. X firması, Y firmasının satışlarının karşılığında Y firmasına sattığı ürün başına komisyon/acenta ücreti ödemektedir.

Veri girişleri altı adet ürünün aylık dönemler itibarıyla X firması ile Y firmasının şubeleri Y1 ve Y2 için satış hasılatı/tutarı bazında yapılmaktadır. Modüldeki örnek veriler (tutarlar ve ürünlerin birim fiyatları) temsili olduğu için ürünlerin birim fiyatları ile satış hasılatları/tutarları matematiksel olarak birbirini doğrulamayabilir. X firması kendisinin veya Z firmasının Y firmasına gönderdiği siparişleri Y’nin Siparişleri sayfasında Y1 ve Y2 şubeleri için ayrı ayrı ve adet bazında takip etmektedir. Y firmasının değişen piyasa koşullarına göre belirli bir ayda hiç sipariş vermemesi ya da birden çok sipariş vermesi söz konusu olabilmektedir. Y firması Y1 ve Y2 şubeleri aracılığıyla X firmasının ürünlerini yurt içinde ve yurt dışında satmasına karşılık, X firmasından ödeme almaktadır. X firması, Y firmasına yapılan ödemeleri Y Acenta Ücretleri sayfasında tutar olarak takip etmektedir.

Modül, temsili iş sürecinin gereği maksimum 13 aylık zaman serisi verilerinden oluşan bir raporlama yapmaktadır. Elbette algoritmalarda değişiklik yaparak, modüle bundan daha fazla ya da daha az veriyi içerecek şekilde raporlama yaptırabilirsiniz.

Modül, raporları oluştururken “ModuleFiles” isimli klasörde yer alan birkaç klasörden ve taslak dosyadan yararlanmaktadır. “ModuleFiles”, “Rapor_Taslak” dizininde yer alan “Taslak” isimli “docm” uzantılı bir Word dosyası bulunmaktadır. Aşağıda ekran görüntüsü verilen “Taslak” isimli dosya içerik olarak büyük ölçüde boştur.

Kapak kısmında rapor adı ve diğer bazı bilgiler ile içerik kısmında ana ve alt başlıklar, grafik ve tablo isimleri, bazı grafik dipnotları vardır. Bunların tümünü, hatta Word dosyasının kendisini de VBA ile oluşturmak mümkündür. Ancak programlamada yaygın olarak bilinen “daha az kodla daha fazla iş yapabilme ilkesi” gereği, bu projede taslak dosya kullanılması tercih edilmiştir.

Excel’de oluşturulan ve/veya dönüştürülen veriler, grafikler, metinler vb. içerikler Word’e nasıl aktarılıyor? Bunu yapmanın çok farklı yolları var. Ancak projelerimde genellikle Word dosyaları içinde kenarlıkları gizlenen tablolar kullanmayı tercih ediyorum. Böylelikle daha az kodla daha fazla iş yapılabilmesinin yanı sıra grafik, tablo, metin vb. içeriklerin hizalanması gibi birçok biçimsel sorun da otomatik olarak çözülmüş oluyor. Yukarıdaki taslak dosyada kenarlıkları gizlenen çok sayıda tablo yer almakta  olup kenarlıkların görünür yapıldığı ekran görüntüsü aşağıdadır.

Burada önemli olan tabloların indeks numaralarını bilmektir. Genellikle en başta yer alan tablonun indeksi 1 olur ve devamındaki tablolar ardışık olarak onu takip eder. İç içe tablolar kullanıldıysa, örneğin indeks numarası 5 olan tablonun içinde başka bir tablo kullanıldıysa onun indeks numarası 6 değil 1 olur; yani 5.1 gibi düşünebilirsiniz. Tabloların indeks numaralarını öğrenmek için Google’da araştırma yapabilirsiniz. Ancak taslak dosyayı açtıktan sonra Alt+F11 kısayolu ile Word’te VBA editörünü açabilirsiniz.

Not: Bilgisayarınızda NVIDIA’nın “GeForce Experience” uygulaması kurulu ise Alt+F11 kısayolu, “GeForce Experience” tarafından varsayılan olarak kullanıldığından, VBA editörünü açmayabilir. Sorunu çözmek için Google’da “GeForce Experience” Alt+F11 kısayolunu değiştirmek şeklinde arama yapıp “GeForce Experience”ın kullandığı Alt+F11 kombinasyonuna farklı bir kısayol kombinasyonu atayabilirsiniz.

Açılan editörde sol tarafta Project (Explorer) kısmında taslak dosyanın “Microsoft Word Object” klasöründe “ThisDocument” objesine çift tıklayınız. Açılan editörde “TableIndex” adında bir prosedür göreceksiniz. Yorum satırını (yeşil satırın başındaki tek denden işaretini kaldırıp) açıp kod haline getirin ve imleç, prosedürün içinde iken Run ediniz. Taslak dosyaya geldiğinizde indeks numarası 16 olan tablonun seçili olduğunu göreceksiniz. Bu şekilde tabloların indeks numaralarını teyit edebilirsiniz. Yukarıdaki açıklamalara ilişkin ekran görüntüsü aşağıdadır.

VBA ile Word’e temel olarak nasıl veri yazıldığını, tabloların indeks numaralarını elde etmeyi gördükten sonra, “ModuleFiles” isimli klasörün içinde yer alan “Operasyon” isimli klasörden bahsedebiliriz. Bu klasörü bir tür mutfak gibi, yani bir yemeği servis etmeden önce yemeği hazırladığınız yer olarak düşünebilirsiniz. “Operasyon” isimli klasörün içinde son oluşturulan rapor vardır. Bu dosyayı silmeniz modülde bir sorun oluşturmaz. Çünkü modül bir sonraki raporu oluşturacağında zaten bu dosyayı silecektir. “Logo” isimli klasörde ise masaüstü kısayolu oluşturulurken kullanılan birkaç png ve ico uzantılı resim dosyası vardır.

Modülün iş analizi ve kurgusu üzerinde yapılan açıklamalardan sonra, artık modülün algoritmalarının analizine geçebiliriz.

3.  Modülün Algoritmik Analizi

Modül esas olarak aşağıdaki üç bölümden oluşur. VBA editörüne ulaşmak için “Raporlama App” isimli Excel dosyasını açtıktan sonra Alt+F11 tuşlarına birlikte basabilirsiniz.

İlk bölüm verilerin girildiği, işlendiği/yazıldığı, grafik şablonlarının yer aldığı arka planda gizlenen çok sayıda çalışma sayfasından oluşan “Microsoft Excel Objects” bölümüdür. İkinci bölümde ise kullanıcı arayüzlerinden olan “Raporlama Arayüzü” ile “Yardım” arayüzlerinden oluşan formlar bölümüdür. Üçüncü bölüm ise ağırlıklı olarak modülün esas fonksiyonları yerine getiren algoritmaların yer aldığı bölümdür.

3.1. ModuleReporting

Yukarıdaki resimde gösterildiği gibi “ModuleReporting” isimli modüle çift tıklayıp söz konusu modülün algoritmalarına ulaşınız. Kaydırma çubuğu ile en altta bulunan “SheetVisible” olarak adlandırdığım prosedüre geliniz. İmleç “SheetVisible” prosedürünün içinde herhangi bir yerde iken prosedürü (sağ üst köşeden) Run ediniz. Bahsi geçen işlemler için aşağıdaki ekran görüntüsünü inceleyebilirsiniz.

 

Sub SheetVisible()
'Projenin üretilmesi, düzenlenmesi ve kontrol edilmesi gibi süreçlerde kullanılmaktadır.
'Bu bölümün modülün çalışmasına herhangi bir etkisi yoktur.
ThisWorkbook.Unprotect "123"

Worksheets(1).Visible = True
Worksheets(2).Visible = True
Worksheets(3).Visible = True
Worksheets(4).Visible = True
Worksheets(5).Visible = True
Worksheets(6).Visible = True
Worksheets(7).Visible = True
Worksheets(8).Visible = True
Worksheets(9).Visible = True
Worksheets(10).Visible = True
Worksheets(11).Visible = True
Worksheets(12).Visible = True
Worksheets(13).Visible = True
Worksheets(14).Visible = True
Worksheets(15).Visible = True
Worksheets(16).Visible = True
Worksheets(17).Visible = True

Worksheets(1).Unprotect Password:="123"
Worksheets(2).Unprotect Password:="123"
Worksheets(3).Unprotect Password:="123"
Worksheets(4).Unprotect Password:="123"
Worksheets(5).Unprotect Password:="123"
Worksheets(6).Unprotect Password:="123"
Worksheets(7).Unprotect Password:="123"
Worksheets(8).Unprotect Password:="123"
Worksheets(9).Unprotect Password:="123"
Worksheets(10).Unprotect Password:="123"
Worksheets(11).Unprotect Password:="123"
Worksheets(12).Unprotect Password:="123"
Worksheets(13).Unprotect Password:="123"
Worksheets(14).Unprotect Password:="123"
Worksheets(15).Unprotect Password:="123"
Worksheets(16).Unprotect Password:="123"
Worksheets(17).Unprotect Password:="123"

With ActiveWindow
    .DisplayHeadings = False
    .DisplayHorizontalScrollBar = True
    .DisplayVerticalScrollBar = True
End With
Application.DisplayFormulaBar = False
ActiveWindow.DisplayGridlines = False

ActiveSheet.DisplayPageBreaks = False

ActiveWindow.ScrollColumn = 1
ActiveWindow.ScrollRow = 1

End Sub

Yukarıdaki prosedürü çalıştırdığınızda tüm sayfa ve kitap korumaları açılacak ve tüm sayfalar görünür olacaktır. Bu yüzden modülün yapısal bütünlüğünün bozulmaması için (veri ekleme/silme/değiştirme, sayfa ekleme, kolon ekleme/kaldırma vb. konularda) dikkatli olunuz. “Raporlama App” isimli Excel dosyasını geri geldiğinizde aşağıdaki ekran görüntüsünde temsil edildiği gibi tüm sayfalar görünür olacaktır.

Not: Eğer modülü kapatıp tekrar açarsanız, modül dosyayı ve tüm sayfaları tekrar kilitler ve ana sayfa hariç tüm sayfaları gizler. Sayfalar arasında (düzenleyici sayfalar hariç) ribbonda yer alan X Verileri, Y1 Verileri gibi bağlantılar aracılıyla dolaşabilirsiniz.

Tekrar “ModuleReporting” isimli modülün en başında yer alan “Raporla” prosedürüne gelelim. “Raporla” prosedürünün içinde her bölümün üstünde gerekli açıklamalar (yeşil rekli ifadeler) yapıldığı için satır satır kodların görevlerinden bahsetmeyeceğim. Kritik ya da anlaşılması nispeten karmaşık bölümlere değinerek ilerleyeceğim.

Ribbonda yer aşan Veri Girişi Grubu altındaki Y Sipariş Verileri hariç diğer dört sayfada yer alan veri satırlarının sayısı ve veri satırlarında yer alan dönemler eşleşmelidir. Raporla prosedürünün başlarında bu eşleşme kontrollerine ilişkin algoritmaları görebilirsiniz. Eşleşmelerin herhangi birinde eksiklik veya yanlışlık varsa kullanıcı bilgilendirilir ve rapor oluşturulmaz.

Excel’in satır ve sütun başlıklarını görüntülemek için aşağıdaki ekran görüntüsünü inceleyebilirsiniz.

Tüm veri sayfalarında veriler 18 no.lu satırdan ve B kolunundan başlamaktadır. Algoritmalarda sık sık karşılacağınız 18 sayısı ile B ifadesi ya da numerik cinsten 2 ifadesi satır ve kolon numaralarını temsil eder. Örneğin X Firmasının veri sayfasında 18 ile 34 no.lu satırlar arasında sırasıyla Ekim 2020 ile Şubat 2022 verileri yer almaktadır. Diğer dört sayfayı incelediğinizde de aynı örüntüyü fark edebilirsiniz. Veri girişleri sırasında bu örüntü bozulursa kullanıcı “Raporlama Arayüzü”nü kullanmaya çalıştığında uyarılacak ve işlem gerçekleştirilmeyecektir. Eğer bu kontroller yapılmaz ise raporlarınız beklendiği kadar temiz ve düzenli oluşturulamayacağı gibi debug/hata da alabilirsiniz.

Yukarıdaki ekran alıntısında görüldüğü gibi bazı alanlar sayısal veriler, bazı alanlara da tarihsel veriler girilmelidir. Bunlarda eksiklik ve/veya yanlışlık olursa da modül kullanıcıyı bilgilendirecek ve işlemi gerçekleştirmeyecektir. Ancak bazı durumdalarda eksik veri olabileceğinden modül bunları tolere edecektir. Benzer şekilde dönem kısmına farklı bir tarih formatı girildiğinde modül bunu da kendi varsayılan tarih formatına dönüştürecektir. Böylece raporlarınız farklı veri formatlarında da standardize edilmiş olacaktır.

“ModuleReporting” içindeki “Raporla” prosedürü “Raporlama Arayüzü” ile senkronize çalışır. “Raporlama Arayüzü” daha sonra açıklanacak olmakla birlikte, “Raporla” prosedürü ile ilişkisi gereği önemli bir noktaya burada değinilecektir. “ModuleReporting” içinde en üstte aşağıdaki ekran görüntüsünde işaretlendiği gibi “Public GlobalIlkSatir As String, GlobalSonSatir As String” şeklinde global iki deklarasyon göreceksiniz.

Bu iki değişken “Raporlama Arayüzü”nde belirli bir değeri aldıktan sonra “Raporla” prosedürünün içinde kullanılmaktadır. Örneğin “Raporlama Arayüzünde” başlangıç ve bitiş tarihi olarak Mayıs 2021 ile Kasım 2021 dönemlerini seçtiğimizi ve arayüzde yer alan “Raporla” butonuna tıkladığımızı varsayalım. Bu durumda “Raporlama Arayüzü”, seçilen dönemleri veri sayfalarında aramaya başlayacak, başlangıç dönemi olan Mayıs 2021 döneminin satır numarası olan 25 ile bitiş döneminin satır numarası olan 31 değerlerini sırasıyla GlobalIlkSatir ve GlobalSonSatir değişkenlerine atayacaktır (X Firmasına ilişkin önceki ekran görüntüsünden değerleri teyit edebilirsiniz). Yani bunlar bize raporlanacak veri döneminin aralığını vermektedir. “ModuleReporting” içindeki “Raporla” prosedüründe, aşağıdaki satırlarda söz konusu global değişkenlerin First_Row ve Last_Row adında ve “Long“ tipinde iki değişkene aktarıldığını göreceksiniz.

 

Option Explicit
Public ShtDelControl As Boolean
Public GlobalIlkTarih As String, GlobalSonTarih As String
Public GlobalIlkSatir As String, GlobalSonSatir As String

Sub Raporla()

Dim Say1 As Long, Say2 As Long, Say3 As Long, Say4 As Long, Say5 As Long
Dim i As Long, j As Long, IlkSatir As Long
Dim m As Long, k As Long, SayAralik As Long
Dim DonemIlk As String, DonemSon As String, TxtAktar As String
Dim myRange As Object

Dim cht As Chart, Ws As Worksheet

Dim AutoPath As String, DestOperasyon As String, SourceRapor As String, ReNameRapor As String
Dim OpenKontrolName As String, OpenControl As String, KontrolFile As String
Dim fso As Object, objWord As Object, objDoc As Object
Dim ContSay As Long, Donem As String, X As Long, DelRowSon As Long, myCounter As Long
Dim First_Row As Long, Last_Row As Long, kaynak As String


Application.EnableEvents = False
Application.ScreenUpdating = False
Application.DisplayAlerts = False

ShtDelControl = True

On Error Resume Next
'Sheetlerin korumasını kaldır ve visible olmasını sağla
For i = 1 To Worksheets.Count - 1 'Sheet sayısı kadar döngü
    Call UnprotectBook
    Worksheets(i).Visible = True
    Worksheets(i).Unprotect Password:="123"
Next i
On Error GoTo 0


'Pathfinder...
AutoPath = ThisWorkbook.Path
DestOperasyon = AutoPath & "\ModuleFiles\Operasyon\"
SourceRapor = AutoPath & "\ModuleFiles\Rapor_Taslak\Taslak.docm"

'ModuleFiles klasör adını kontrol et.
If Not Dir(AutoPath & "\ModuleFiles\", vbDirectory) <> vbNullString Then
    MsgBox AutoPath & "\ModuleFiles\" & " dizinine ulaşılamıyor. Bu dizine ait ModuleFiles isimli klasörün adında değişiklik yapılmış, ModuleFiles isimli klasör silinmiş veya Raporlama App isimli uygulama dosyası ModuleFiles isimli klasörden farklı bir dizinde olabilir.", vbOKOnly + vbCritical, "ishakkutlu.com"
    GoTo Son
End If
'Operasyon klasörü yoksa oluştur.
If Not Dir(DestOperasyon, vbDirectory) <> vbNullString Then
    MkDir DestOperasyon
End If
'Taslak'ı kontrol et.
If Not Dir(SourceRapor, vbDirectory) <> vbNullString Then
    MsgBox SourceRapor & " dizinine ulaşılamıyor. Bu dizine ait klasörlerin ve/veya dosyaların isimlerinde değişiklik yapılmış olabilir.", vbOKOnly + vbCritical, "ishakkutlu.com"
    GoTo Son
End If

'__________________________________________________________

'Veri girişi sayfalarındaki son satırları bul
Say1 = Worksheets(1).Range("B" & Rows.Count).End(xlUp).Row
Say2 = Worksheets(2).Range("B" & Rows.Count).End(xlUp).Row
Say3 = Worksheets(3).Range("B" & Rows.Count).End(xlUp).Row
Say4 = Worksheets(4).Range("B" & Rows.Count).End(xlUp).Row
Say5 = Worksheets(5).Range("B" & Rows.Count).End(xlUp).Row

'Hiçbir sayfada veri yoksa prosedürü başlatma
If Say1 < 18 Or Say2 < 18 Or Say3 < 18 Or Say4 < 18 Or Say5 < 18 Then
    GoTo Son
End If

'Satır sayılarının kontrolü (Dört sayfanın veri girişleri senkronize olmak zorunda!)
If Say1 = Say2 And Say2 = Say3 And Say3 = Say5 Then
    '
Else
    MsgBox "Y'nin Acenta Ücreti ile X, Y1 ve Y2 firma sayfalarının satır adetlerinde eşleşme sağlanamadığından işleminiz gerçekleştirilemiyor. Söz konusu sayfalarda, veri girişi yapılan satır sayısı aynı olmalıdır.", vbOKOnly + vbCritical, "ishakkutlu.com"
    GoTo Son
End If

'Dönem eşleşmeleri (Dört sayfanın veri dönemleri senkronize olmak zorunda!)
For i = 18 To Say1
    If Month(Worksheets(1).Cells(i, 2)) = Month(Worksheets(2).Cells(i, 2)) And Month(Worksheets(2).Cells(i, 2)) = Month(Worksheets(3).Cells(i, 2)) And Month(Worksheets(3).Cells(i, 2)) = Month(Worksheets(5).Cells(i, 2)) Then
        
    Else
        MsgBox "Y'nin Acenta Ücreti ile X, Y1 ve Y2 firma sayfalarının dönemlerinde eşleşme sağlanamadığından işleminiz gerçekleştirilemiyor. Dört sayfada da veri girişi yapılan dönemler uyumlu olmalıdır.", vbOKOnly + vbCritical, "ishakkutlu.com"
        GoTo Son
    End If
Next i

'_____________Sayısal karakter kontrolü

'Yurt içi satışlar
For i = 18 To Say1
    For j = 3 To 8
        If Worksheets(1).Cells(i, j) <> "" And IsNumeric(Worksheets(1).Cells(i, j)) = False Then
            MsgBox "X sayfasının satırlarında sayısal olmayan veri tespit edildiği için işleminiz gerçekleştirilemiyor.", vbOKOnly + vbCritical, "ishakkutlu.com"
            GoTo Son
        ElseIf Worksheets(2).Cells(i, j) <> "" And IsNumeric(Worksheets(2).Cells(i, j)) = False Then
            MsgBox "Y1 sayfasının satırlarında sayısal olmayan veri tespit edildiği için işleminiz gerçekleştirilemiyor.", vbOKOnly + vbCritical, "ishakkutlu.com"
            GoTo Son
        ElseIf Worksheets(3).Cells(i, j) <> "" And IsNumeric(Worksheets(3).Cells(i, j)) = False Then
            MsgBox "Y2 sayfasının satırlarında sayısal olmayan veri tespit edildiği için işleminiz gerçekleştirilemiyor.", vbOKOnly + vbCritical, "ishakkutlu.com"
            GoTo Son
        End If
    Next j
Next i
For i = 18 To Say1 '(Yurt dışı satışlar)
    For j = 11 To 16
        If Worksheets(1).Cells(i, j) <> "" And IsNumeric(Worksheets(1).Cells(i, j)) = False Then
            MsgBox "X sayfasının satırlarında sayısal olmayan veri tespit edildiği için işleminiz gerçekleştirilemiyor.", vbOKOnly + vbCritical, "ishakkutlu.com"
            GoTo Son
        ElseIf Worksheets(2).Cells(i, j) <> "" And IsNumeric(Worksheets(2).Cells(i, j)) = False Then
            MsgBox "Y1 sayfasının satırlarında sayısal olmayan veri tespit edildiği için işleminiz gerçekleştirilemiyor.", vbOKOnly + vbCritical, "ishakkutlu.com"
            GoTo Son
        ElseIf Worksheets(3).Cells(i, j) <> "" And IsNumeric(Worksheets(3).Cells(i, j)) = False Then
            MsgBox "Y2 sayfasının satırlarında sayısal olmayan veri tespit edildiği için işleminiz gerçekleştirilemiyor.", vbOKOnly + vbCritical, "ishakkutlu.com"
            GoTo Son
        End If
    Next j
Next i
For i = 18 To Say1 '(Y'nin acenta ücreti)
    For j = 3 To 5
        If Worksheets(5).Cells(i, j) <> "" And IsNumeric(Worksheets(5).Cells(i, j)) = False Then
            MsgBox "Y'nin Acenta Ücreti sayfasının satırlarında sayısal olmayan veri tespit edildiği için işleminiz gerçekleştirilemiyor.", vbOKOnly + vbCritical, "ishakkutlu.com"
            GoTo Son
        End If
    Next j
Next i
For i = 18 To Say4 '(Y'nin siparişleri)
    For j = 6 To 11
        If Worksheets(4).Cells(i, j) <> "" And IsNumeric(Worksheets(4).Cells(i, j)) = False Then
            MsgBox "Y'nin Siparişleri sayfasının satırlarında sayısal olmayan veri tespit edildiği için işleminiz gerçekleştirilemiyor.", vbOKOnly + vbCritical, "ishakkutlu.com"
            GoTo Son
        End If
    Next j
Next i


'__________________________________________________________


DelRowSon = Say1
If DelRowSon < 19 Then 'Satırların silinmesi sırasında ilk satırın silinmemesi için (İŞARET1'e BAK)
    DelRowSon = 19
End If

'Global değişkenleri aktar
First_Row = GlobalIlkSatir
Last_Row = GlobalSonSatir
SayAralik = Last_Row - First_Row + 18

'DÖNEM BAŞI ve DÖNEM SONU TESPİTİ
'Yukarıda, firma dönemlerinin senkronizasyon kontrolü yapıldığı için sadece bir firmanın dönemine bakmak yeterli olacaktır.
DonemIlk = Format(Worksheets(1).Cells(First_Row, 2), "mmmm yyyy")
DonemSon = Format(Worksheets(1).Cells(Last_Row, 2), "mmmm yyyy")
'MsgBox DonemIlk & " ve " & DonemSon

'Formatlar (Kullanıcı farklı formatta tarih, sayısal vb. veri girdiğinde onları standardize et.)
Worksheets(11).Range("B18:P18").Copy 'Arka planda bir format sayfası
Worksheets(1).Range("B" & 18 & ":P" & Say1).PasteSpecial xlFormats
Worksheets(2).Range("B" & 18 & ":P" & Say1).PasteSpecial xlFormats
Worksheets(3).Range("B" & 18 & ":P" & Say1).PasteSpecial xlFormats

Worksheets(11).Range("B18:X18").Copy
Worksheets(6).Range("B" & 18 & ":X" & SayAralik).PasteSpecial xlFormats
Worksheets(7).Range("B" & 18 & ":X" & SayAralik).PasteSpecial xlFormats
Worksheets(8).Range("B" & 18 & ":X" & SayAralik).PasteSpecial xlFormats
Worksheets(12).Range("B" & 18 & ":X" & SayAralik).PasteSpecial xlFormats 'X firmasının satır sayısına (Say1'e) eşit olacaktır.

'Düzenleme sayfalarını temizle
Worksheets(6).Rows("18:" & DelRowSon).EntireRow.Delete
Worksheets(7).Rows("18:" & DelRowSon).EntireRow.Delete
Worksheets(8).Rows("18:" & DelRowSon).EntireRow.Delete
Worksheets(12).Rows("18:" & DelRowSon).EntireRow.Delete

'İlk satırların formatlarını koru (İŞARET1'e BAK)
Worksheets(9).Range("B18:H18").ClearContents
Worksheets(9).Rows("19:" & DelRowSon).EntireRow.Delete
Worksheets(10).Range("B18:E18").ClearContents
Worksheets(10).Rows("19:" & DelRowSon).EntireRow.Delete
Worksheets(13).Range("B18:W18").ClearContents
Worksheets(13).Rows("19:" & DelRowSon).EntireRow.Delete
Worksheets(14).Range("B18:X18").ClearContents
Worksheets(14).Rows("19:" & DelRowSon).EntireRow.Delete

'X ve Y firmasının Y1 ve Y2 şubelerinin yurt içi satış adetlerini hesapla (Maksimum 13 Aylık)
myCounter = 18
For i = First_Row To Last_Row
    'Adetleri elde etmek için ürünlerin satış tutarlarını ürün fiyatlarına böl
    For j = 3 To 8
        Worksheets(6).Cells(myCounter, j) = Worksheets(1).Cells(i, j) / Worksheets(1).Cells(17, j)
        Worksheets(7).Cells(myCounter, j) = Worksheets(2).Cells(i, j) / Worksheets(2).Cells(17, j)
        Worksheets(8).Cells(myCounter, j) = Worksheets(3).Cells(i, j) / Worksheets(3).Cells(17, j)
    Next j
    'Dönemler
    Worksheets(6).Cells(myCounter, 2) = Worksheets(1).Cells(i, 2)
    Worksheets(7).Cells(myCounter, 2) = Worksheets(2).Cells(i, 2)
    Worksheets(8).Cells(myCounter, 2) = Worksheets(3).Cells(i, 2)
    
    myCounter = myCounter + 1
Next i

'X ve Y firmasının Y1 ve Y2 şubelerinin yurt dışı satış adetlerini hesapla (Maksimum 13 Aylık)
myCounter = 18
For i = First_Row To Last_Row
    'Adetleri elde etmek için ürünlerin satış tutarlarını ürün fiyatlarına böl
    For j = 11 To 16
        Worksheets(6).Cells(myCounter, j) = Worksheets(1).Cells(i, j) / Worksheets(1).Cells(17, j)
        Worksheets(7).Cells(myCounter, j) = Worksheets(2).Cells(i, j) / Worksheets(2).Cells(17, j)
        Worksheets(8).Cells(myCounter, j) = Worksheets(3).Cells(i, j) / Worksheets(3).Cells(17, j)
    Next j
    'Dönemler
    Worksheets(6).Cells(myCounter, 10) = Worksheets(1).Cells(i, 2)
    Worksheets(7).Cells(myCounter, 10) = Worksheets(2).Cells(i, 2)
    Worksheets(8).Cells(myCounter, 10) = Worksheets(3).Cells(i, 2)
    
    myCounter = myCounter + 1
Next i

'X ve Y firmasının Y1 ve Y2 şubelerinin yurt içi ve dışı TOPLAM satış adetlerini hesapla (Maksimum 13 Aylık)
myCounter = 18
For i = 18 To SayAralik
    'Adetleri elde etmek için yurt içi ve dışı satış adetlerini topla
    For j = 19 To 24
        Worksheets(6).Cells(myCounter, j) = Worksheets(6).Cells(i, j - 16) + Worksheets(6).Cells(i, j - 8)
        Worksheets(7).Cells(myCounter, j) = Worksheets(7).Cells(i, j - 16) + Worksheets(7).Cells(i, j - 8)
        Worksheets(8).Cells(myCounter, j) = Worksheets(8).Cells(i, j - 16) + Worksheets(8).Cells(i, j - 8)
    Next j
    'Dönemler
    Worksheets(6).Cells(myCounter, 18) = Worksheets(6).Cells(i, 2)
    Worksheets(7).Cells(myCounter, 18) = Worksheets(7).Cells(i, 2)
    Worksheets(8).Cells(myCounter, 18) = Worksheets(8).Cells(i, 2)
    
    myCounter = myCounter + 1
Next i

'__________________________________________________________

If myCounter = 18 Then
    myCounter = 19
End If
'Y1 ve Y2 şubelerinin yurt içi satış adetlerini Y firmasında konsolide et (Maksimum 13 Aylık)
For i = 18 To myCounter - 1
    'Adetler
    For j = 3 To 8
        Worksheets(12).Cells(i, j) = Worksheets(7).Cells(i, j) + Worksheets(8).Cells(i, j)
    Next j
    'Dönemler
    Worksheets(12).Cells(i, 2) = Worksheets(7).Cells(i, 2)
Next i

'Y1 ve Y2 şubelerinin yurt dışı satış adetlerini Y firmasında konsolide et (Maksimum 13 Aylık)
For i = 18 To myCounter - 1
    'Adetler
    For j = 11 To 16
        Worksheets(12).Cells(i, j) = Worksheets(7).Cells(i, j) + Worksheets(8).Cells(i, j)
    Next j
    'Dönemler
    Worksheets(12).Cells(i, 10) = Worksheets(7).Cells(i, 2)
Next i

'Y1 ve Y2 şubelerinin yurt içi ve dışı satış adetleri TOPLAMINI Y firmasında konsolide et (Maksimum 13 Aylık)
For i = 18 To myCounter - 1
    'Adetler
    For j = 19 To 24
        Worksheets(12).Cells(i, j) = Worksheets(7).Cells(i, j) + Worksheets(8).Cells(i, j)
    Next j
    'Dönemler
    Worksheets(12).Cells(i, 18) = Worksheets(7).Cells(i, 2)
Next i

'__________________________________________________________


'X ve konsolide Y'nin kıyaslanması

'X firmasının yurt içi ve dışı ile TOPLAM satış adetlerini pay hesaplaması için PAYLAR (X, Y) SAYFASINA aktar (Maksimum 13 Aylık)
For i = 18 To myCounter - 1
    Worksheets(13).Range("E" & i) = Application.WorksheetFunction.Sum(Worksheets(6).Range("C" & i & ":H" & i))
    'Dönemler
    Worksheets(13).Cells(i, 2) = Worksheets(6).Cells(i, 2)
    
    Worksheets(13).Range("M" & i) = Application.WorksheetFunction.Sum(Worksheets(6).Range("K" & i & ":P" & i))
    'Dönemler
    Worksheets(13).Cells(i, 10) = Worksheets(6).Cells(i, 2)

    Worksheets(13).Range("U" & i) = Application.WorksheetFunction.Sum(Worksheets(6).Range("S" & i & ":X" & i))
    'Dönemler
    Worksheets(13).Cells(i, 18) = Worksheets(6).Cells(i, 2)
Next i

'Y firmasının yurt içi ve dışı ile TOPLAM satış adetlerini pay hesaplaması için PAYLAR (X, Y) SAYFASINA aktar (Maksimum 13 Aylık)
For i = 18 To myCounter - 1
    Worksheets(13).Range("F" & i) = Application.WorksheetFunction.Sum(Worksheets(12).Range("C" & i & ":H" & i))
    Worksheets(13).Range("N" & i) = Application.WorksheetFunction.Sum(Worksheets(12).Range("K" & i & ":P" & i))
    Worksheets(13).Range("V" & i) = Application.WorksheetFunction.Sum(Worksheets(12).Range("S" & i & ":X" & i))
Next i

'X ve Y firmasının yurt içi ve dışı toplam satış adetleri ile tüm satışların toplamını hesapla (Maksimum 13 Aylık)
For i = 18 To myCounter - 1
    Worksheets(13).Range("G" & i) = Application.WorksheetFunction.Sum(Worksheets(13).Range("E" & i & ":F" & i))
    Worksheets(13).Range("O" & i) = Application.WorksheetFunction.Sum(Worksheets(13).Range("M" & i & ":N" & i))
    Worksheets(13).Range("W" & i) = Application.WorksheetFunction.Sum(Worksheets(13).Range("U" & i & ":V" & i))
Next i

'X ve Y firmalarının paylarını hesapla (Maksimum 13 Aylık)
For i = 18 To myCounter - 1
    Worksheets(13).Range("C" & i) = 100 * (Worksheets(13).Range("E" & i) / Worksheets(13).Range("G" & i))
    Worksheets(13).Range("D" & i) = 100 * (Worksheets(13).Range("F" & i) / Worksheets(13).Range("G" & i))

    Worksheets(13).Range("K" & i) = 100 * (Worksheets(13).Range("M" & i) / Worksheets(13).Range("O" & i))
    Worksheets(13).Range("L" & i) = 100 * (Worksheets(13).Range("N" & i) / Worksheets(13).Range("O" & i))

    Worksheets(13).Range("S" & i) = 100 * (Worksheets(13).Range("U" & i) / Worksheets(13).Range("W" & i))
    Worksheets(13).Range("T" & i) = 100 * (Worksheets(13).Range("V" & i) / Worksheets(13).Range("W" & i))
Next i

'Formatlar
Worksheets(13).Range("B18:W18").Copy 'Tüm satırları ilk satırın formatına dönüştür
Worksheets(13).Range("B" & 18 & ":W" & myCounter - 1).PasteSpecial xlFormats

'__________________________________________________________

'X ve Y'nin şubelerinin kıyaslanması (Bir önceki kod bloğuna çok benzer)

'X firmasının yurt içi ve dışı ile TOPLAM satış adetlerini pay hesaplaması için PAYLAR (X, Y1, Y2) SAYFASINA aktar (Maksimum 13 Aylık)
For i = 18 To myCounter - 1
    Worksheets(14).Range("F" & i) = Application.WorksheetFunction.Sum(Worksheets(6).Range("C" & i & ":H" & i))
    'Dönemler
    Worksheets(14).Cells(i, 2) = Worksheets(6).Cells(i, 2)
    
    Worksheets(14).Range("N" & i) = Application.WorksheetFunction.Sum(Worksheets(6).Range("K" & i & ":P" & i))
    'Dönemler
    Worksheets(14).Cells(i, 10) = Worksheets(6).Cells(i, 2)

    Worksheets(14).Range("V" & i) = Application.WorksheetFunction.Sum(Worksheets(6).Range("S" & i & ":X" & i))
    'Dönemler
    Worksheets(14).Cells(i, 18) = Worksheets(6).Cells(i, 2)
Next i

'Y1 firmasının/şubesinin yurt içi ve dışı ile TOPLAM satış adetlerini pay hesaplaması için PAYLAR (X, Y1, Y2) SAYFASINA aktar (Maksimum 13 Aylık)
For i = 18 To myCounter - 1
    Worksheets(14).Range("G" & i) = Application.WorksheetFunction.Sum(Worksheets(7).Range("C" & i & ":H" & i))
    Worksheets(14).Range("O" & i) = Application.WorksheetFunction.Sum(Worksheets(7).Range("K" & i & ":P" & i))
    Worksheets(14).Range("W" & i) = Application.WorksheetFunction.Sum(Worksheets(7).Range("S" & i & ":X" & i))
Next i

'Y2 firmasının/şubesinin yurt içi ve dışı ile TOPLAM satış adetlerini pay hesaplaması için PAYLAR (X, Y1, Y2) SAYFASINA aktar (Maksimum 13 Aylık)
For i = 18 To myCounter - 1
    Worksheets(14).Range("H" & i) = Application.WorksheetFunction.Sum(Worksheets(8).Range("C" & i & ":H" & i))
    Worksheets(14).Range("P" & i) = Application.WorksheetFunction.Sum(Worksheets(8).Range("K" & i & ":P" & i))
    Worksheets(14).Range("X" & i) = Application.WorksheetFunction.Sum(Worksheets(8).Range("S" & i & ":X" & i))
Next i


'X, Y1 ve Y2 firmasının/şubesinin paylarını hesapla (Maksimum 13 Aylık)
For i = 18 To myCounter - 1
    Worksheets(14).Range("C" & i) = 100 * (Worksheets(14).Range("F" & i) / Application.WorksheetFunction.Sum(Worksheets(14).Range("F" & i & ":H" & i)))
    Worksheets(14).Range("D" & i) = 100 * (Worksheets(14).Range("G" & i) / Application.WorksheetFunction.Sum(Worksheets(14).Range("F" & i & ":H" & i)))
    Worksheets(14).Range("E" & i) = 100 * (Worksheets(14).Range("H" & i) / Application.WorksheetFunction.Sum(Worksheets(14).Range("F" & i & ":H" & i)))

    Worksheets(14).Range("K" & i) = 100 * (Worksheets(14).Range("N" & i) / Application.WorksheetFunction.Sum(Worksheets(14).Range("N" & i & ":P" & i)))
    Worksheets(14).Range("L" & i) = 100 * (Worksheets(14).Range("O" & i) / Application.WorksheetFunction.Sum(Worksheets(14).Range("N" & i & ":P" & i)))
    Worksheets(14).Range("M" & i) = 100 * (Worksheets(14).Range("P" & i) / Application.WorksheetFunction.Sum(Worksheets(14).Range("N" & i & ":P" & i)))

    Worksheets(14).Range("S" & i) = 100 * (Worksheets(14).Range("V" & i) / Application.WorksheetFunction.Sum(Worksheets(14).Range("V" & i & ":X" & i)))
    Worksheets(14).Range("T" & i) = 100 * (Worksheets(14).Range("W" & i) / Application.WorksheetFunction.Sum(Worksheets(14).Range("V" & i & ":X" & i)))
    Worksheets(14).Range("U" & i) = 100 * (Worksheets(14).Range("X" & i) / Application.WorksheetFunction.Sum(Worksheets(14).Range("V" & i & ":X" & i)))
Next i

'Formatlar
Worksheets(14).Range("B18:X18").Copy
Worksheets(14).Range("B" & 18 & ":X" & myCounter - 1).PasteSpecial xlFormats

'__________________________________________________________


'siparişler
Worksheets(1).Range("B" & First_Row & ":B" & Last_Row).Copy Worksheets(9).Range("B18" & ":B" & SayAralik)
For j = 18 To SayAralik
    i = 18
    Do While i <= Say4
        If Month(Worksheets(4).Cells(i, 2)) = Month(Worksheets(9).Cells(j, 2)) And Year(Worksheets(4).Cells(i, 2)) = Year(Worksheets(9).Cells(j, 2)) Then
            Worksheets(9).Cells(j, 3) = Worksheets(9).Cells(j, 3) + Worksheets(4).Cells(i, 6)
            Worksheets(9).Cells(j, 4) = Worksheets(9).Cells(j, 4) + Worksheets(4).Cells(i, 7)
            Worksheets(9).Cells(j, 5) = Worksheets(9).Cells(j, 5) + Worksheets(4).Cells(i, 8)
            Worksheets(9).Cells(j, 6) = Worksheets(9).Cells(j, 6) + Worksheets(4).Cells(i, 9)
            Worksheets(9).Cells(j, 7) = Worksheets(9).Cells(j, 7) + Worksheets(4).Cells(i, 10)
            Worksheets(9).Cells(j, 8) = Worksheets(9).Cells(j, 8) + Worksheets(4).Cells(i, 11)
        End If
        i = i + 1
    Loop
Next j
'Boş hücrelere 0 yaz.
For j = 18 To SayAralik
    For i = 3 To 8
        If Worksheets(9).Cells(j, i) = "" Then
            Worksheets(9).Cells(j, i) = 0
        End If
    Next i
Next j

SiparisAtla:

'Formatlar
Worksheets(4).Range("B18:K18").Copy
Worksheets(4).Range("B" & 18 & ":K" & Say4).PasteSpecial xlFormats
Worksheets(11).Range("B18:H18").Copy
Worksheets(9).Range("B18" & ":H" & SayAralik).PasteSpecial xlFormats

'__________________________________________________________

'Acenta ücreti
Worksheets(5).Range("B" & First_Row & ":E" & Last_Row).Copy
Worksheets(10).Range("B18:E" & SayAralik).PasteSpecial xlPasteValues

'Formatlar
Worksheets(5).Range("B18:E18").Copy
Worksheets(5).Range("B" & 18 & ":E" & Say5).PasteSpecial xlFormats
Worksheets(10).Range("B18:E18").Copy
Worksheets(10).Range("B18" & ":E" & SayAralik).PasteSpecial xlFormats

'__________________________________________________________

IlkSatir = 18
'GRAFİKLER
On Error Resume Next
'Grafik 1
Set Ws = Worksheets(6)
Set cht = Worksheets(15).ChartObjects("Chart 1").Chart
cht.SetSourceData Source:=Ws.Range("R" & IlkSatir & ":X" & SayAralik) 'Grafik veri kaynağını güncelle
'Grafik seri isimlerini oluştur
cht.SeriesCollection(1).Name = Ws.Range("S17")
cht.SeriesCollection(2).Name = Ws.Range("T17")
cht.SeriesCollection(3).Name = Ws.Range("U17")
cht.SeriesCollection(4).Name = Ws.Range("V17")
cht.SeriesCollection(5).Name = Ws.Range("W17")
cht.SeriesCollection(6).Name = Ws.Range("X17")
'Grafik boyutları
cht.ChartArea.Height = 177 '6,4 cm
cht.ChartArea.Width = 210 '220 '8 cm


'Grafik 2
Set Ws = Worksheets(12)
Set cht = Worksheets(15).ChartObjects("Chart 2").Chart
cht.SetSourceData Source:=Ws.Range("R" & IlkSatir & ":X" & SayAralik)
cht.SeriesCollection(1).Name = Ws.Range("S17")
cht.SeriesCollection(2).Name = Ws.Range("T17")
cht.SeriesCollection(3).Name = Ws.Range("U17")
cht.SeriesCollection(4).Name = Ws.Range("V17")
cht.SeriesCollection(5).Name = Ws.Range("W17")
cht.SeriesCollection(6).Name = Ws.Range("X17")
'Grafik boyutları
cht.ChartArea.Height = 177 '6,4 cm
cht.ChartArea.Width = 210 '220 '8 cm

'Grafik 3
Set Ws = Worksheets(13)
Set cht = Worksheets(15).ChartObjects("Chart 3").Chart
cht.SetSourceData Source:=Ws.Range("B" & IlkSatir & ":G" & SayAralik)
cht.SeriesCollection(1).Name = Ws.Range("C17")
cht.SeriesCollection(2).Name = Ws.Range("D17")
cht.SeriesCollection(3).Name = Ws.Range("E17")
cht.SeriesCollection(4).Name = Ws.Range("F17")
cht.SeriesCollection(5).Name = Ws.Range("G17")
'Grafik boyutları
cht.ChartArea.Height = 177 '6,4 cm
cht.ChartArea.Width = 210 '220 '8 cm

'Grafik 4
Set Ws = Worksheets(13)
Set cht = Worksheets(15).ChartObjects("Chart 4").Chart
cht.SetSourceData Source:=Ws.Range("J" & IlkSatir & ":O" & SayAralik)
cht.SeriesCollection(1).Name = Ws.Range("K17")
cht.SeriesCollection(2).Name = Ws.Range("L17")
cht.SeriesCollection(3).Name = Ws.Range("M17")
cht.SeriesCollection(4).Name = Ws.Range("N17")
cht.SeriesCollection(5).Name = Ws.Range("O17")
'Grafik boyutları
cht.ChartArea.Height = 177 '6,4 cm
cht.ChartArea.Width = 210 '220 '8 cm

'Grafik 5
Set Ws = Worksheets(13)
Set cht = Worksheets(15).ChartObjects("Chart 5").Chart
cht.SetSourceData Source:=Ws.Range("R" & IlkSatir & ":W" & SayAralik)
cht.SeriesCollection(1).Name = Ws.Range("S17")
cht.SeriesCollection(2).Name = Ws.Range("T17")
cht.SeriesCollection(3).Name = Ws.Range("U17")
cht.SeriesCollection(4).Name = Ws.Range("V17")
cht.SeriesCollection(5).Name = Ws.Range("W17")
'Grafik boyutları
cht.ChartArea.Height = 177 '6,4 cm
cht.ChartArea.Width = 277 '10 cm

'Grafik 6
Set Ws = Worksheets(14)
Set cht = Worksheets(15).ChartObjects("Chart 6").Chart
cht.SetSourceData Source:=Ws.Range("B" & IlkSatir & ":E" & SayAralik)
cht.SeriesCollection(1).Name = Ws.Range("C17")
cht.SeriesCollection(2).Name = Ws.Range("D17")
cht.SeriesCollection(3).Name = Ws.Range("E17")
'Grafik boyutları
cht.ChartArea.Height = 177 '6,4 cm
cht.ChartArea.Width = 210 '220 '8 cm

'Grafik 7
Set Ws = Worksheets(14)
Set cht = Worksheets(15).ChartObjects("Chart 7").Chart
cht.SetSourceData Source:=Ws.Range("J" & IlkSatir & ":M" & SayAralik)
cht.SeriesCollection(1).Name = Ws.Range("K17")
cht.SeriesCollection(2).Name = Ws.Range("L17")
cht.SeriesCollection(3).Name = Ws.Range("M17")
'Grafik boyutları
cht.ChartArea.Height = 177 '6,4 cm
cht.ChartArea.Width = 210 '220 '8 cm

'Grafik 8
Set Ws = Worksheets(14)
Set cht = Worksheets(15).ChartObjects("Chart 8").Chart
cht.SetSourceData Source:=Ws.Range("R" & IlkSatir & ":U" & SayAralik)
cht.SeriesCollection(1).Name = Ws.Range("S17")
cht.SeriesCollection(2).Name = Ws.Range("T17")
cht.SeriesCollection(3).Name = Ws.Range("U17")
'Grafik boyutları
cht.ChartArea.Height = 177 '6,4 cm
cht.ChartArea.Width = 277 '10 cm

'Grafik 9
Set Ws = Worksheets(10)
Set cht = Worksheets(15).ChartObjects("Chart 9").Chart
cht.SetSourceData Source:=Ws.Range("B" & IlkSatir & ":D" & SayAralik)
cht.SeriesCollection(1).Name = Ws.Range("C17")
cht.SeriesCollection(2).Name = Ws.Range("D17")
'cht.SeriesCollection(3).Name = ws.Range("E17")
'Grafik boyutları
cht.ChartArea.Height = 177 '6,4 cm
cht.ChartArea.Width = 277 '10 cm

'Grafik 10
Set Ws = Worksheets(9)
Set cht = Worksheets(15).ChartObjects("Chart 10").Chart
cht.SetSourceData Source:=Ws.Range("B" & IlkSatir & ":H" & SayAralik)
cht.SeriesCollection(1).Name = Ws.Range("C17")
cht.SeriesCollection(2).Name = Ws.Range("D17")
cht.SeriesCollection(3).Name = Ws.Range("E17")
cht.SeriesCollection(4).Name = Ws.Range("F17")
cht.SeriesCollection(5).Name = Ws.Range("G17")
cht.SeriesCollection(6).Name = Ws.Range("H17")
'Grafik boyutları
cht.ChartArea.Height = 177 '6,4 cm
cht.ChartArea.Width = 277 '10 cm


'WORD'e AKTARIM

'________________________________________

'    'Pathfinder...
'    AutoPath = ThisWorkbook.Path
'    DestOperasyon = AutoPath & "\ModuleFiles\Operasyon\"
'    SourceRapor = AutoPath & "\ModuleFiles\Rapor_Taslak\Taslak.docm"

    'Rapor dönemi (Son tarih + 1 ay)
    Donem = Format(DateAdd("m", 1, DonemSon), "mmmm yyyy")
    ReNameRapor = "Teknik Rapor " & Donem

    'Operasyon klasöründeki docm uzantılı word dosyalarından açık olanları kapat ve temizle.
    OpenKontrolName = Dir(DestOperasyon & "*.docm")
    Do While OpenKontrolName <> ""
        OpenControl = IsFileOpen(DestOperasyon & OpenKontrolName)
        If OpenControl = True Then 'Açıksa
            On Error Resume Next
            Set objWord = GetObject(, "Word.Application")
            Set objWord = GetObject(, "Word.Application")
            Set objWord = GetObject(, "Word.Application")
            Set objWord = GetObject(, "Word.Application")
            Set objWord = GetObject(, "Word.Application")
            Set objDoc = GetObject(DestOperasyon & ReNameRapor & ".docm")
            objDoc.Close SaveChanges:=False
            objWord.Quit SaveChanges:=True
            'MsgBox "Dosya OpenKontrol methodu ile kapatıldı."
        End If
        OpenKontrolName = Dir()
    Loop

    'Close the all Word application
    Call ModuleSystem.OpenWordControl
    
    Set objWord = Nothing
    Set objDoc = Nothing

'________________________________________

    'On Error Resume Next
    'Operasyon klasörünün içindeki tüm dosyaları sil (txt, docm vb.)
    ContSay = 0
    KontrolFile = Dir(DestOperasyon & "*.???")
    Do While KontrolFile <> ""
        ContSay = ContSay + 1
        KontrolFile = Dir()
    Loop
    If ContSay > 0 Then
        On Error Resume Next
        Kill DestOperasyon & "*.???"
    End If

    'Dosyayı Taslaktan operasyon klasörüne kopyala ve adını değiştir.
    Set fso = CreateObject("Scripting.FileSystemObject")
    fso.CopyFile (SourceRapor), DestOperasyon & ReNameRapor & ".docm", True
'________________________________________

    'Oluşturulacak dosyayı aç
    On Error Resume Next
    Set objWord = GetObject(, "Word.Application")
    Set objWord = GetObject(, "Word.Application")
    Set objWord = GetObject(, "Word.Application")
    Set objWord = GetObject(, "Word.Application")
    Set objWord = GetObject(, "Word.Application")

On Error GoTo 0

    If objWord Is Nothing Then
        'MsgBox "Dosya oluşturmada CreateObject methodu kullanılacak."
        Set objWord = CreateObject("Word.Application")
        objWord.Visible = False
    Else
        Set objWord = CreateObject("Word.Application")
        objWord.Visible = False
    End If
    objWord.Documents.Open FileName:=DestOperasyon & ReNameRapor & ".docm"
    objWord.Visible = True
    objWord.Activate 'Ekrana getirir.
    objWord.Visible = True 'False
    objWord.Application.WindowState = wdWindowStateMaximize
    
    Set objDoc = GetObject(DestOperasyon & ReNameRapor & ".docm")
'________________________________________

'Cancel to On Error Resume Next
On Error GoTo 0

'Taslak dosyanın içerdiği tablo sayısının algortimaya uyumunu kontrol et
If objDoc.Tables.Count = 16 Then
    '
Else
   MsgBox "Taslak dosyada grafiklerin, tabloların veya metinlerin yuvalanacağı tablolarda eksiklik tespit edildi.", vbOKOnly + vbCritical, "ishakkutlu.com"
   GoTo SablondaTabloEksik
End If


'ÜST BİLGİYİ DÜZENLE
'___________________________________________

'Pane aç (BAŞLANGIÇ)
If objDoc.ActiveWindow.View.SplitSpecial <> wdPaneNone Then
    objDoc.ActiveWindow.Panes(2).Close
End If
If objDoc.ActiveWindow.ActivePane.View.Type = wdNormalView Or objDoc.ActiveWindow.ActivePane.View.Type = wdOutlineView Then
    objDoc.ActiveWindow.ActivePane.View.Type = wdPrintView
End If
'_____

'Header'a metni ve sayfa no.'yu ekle
Set myRange = objDoc.Sections(1).Headers(wdHeaderFooterPrimary).Range
With myRange
    .InsertAfter Text:="Teknik Rapor: VBA ile raporları otomatize etmek | " & Donem & " | "
    .Fields.Add Range:=.Characters.Last, Type:=wdFieldEmpty, Text:="PAGE", PreserveFormatting:=False
    '.InsertAfter Text:=". sayfası"
End With
myRange.Font.TextColor = RGB(204, 80, 85) 'Sayfa no dahil tüm metni 11 punto ve kırmızı yap
myRange.Font.Size = 11
'Sayfa no hariç metnin yazı boyutunu 9 yap ve rengini değiştir.
TxtAktar = "Teknik Rapor: VBA ile raporları otomatize etmek | " & Donem & " | " 'Sayfa hariç tüm metni9 punto ve lacivert yap
Set myRange = objDoc.Sections(1).Headers(1).Range
myRange.Find.Execute FindText:=TxtAktar
myRange.Font.TextColor = RGB(0, 23, 58)
myRange.Font.Size = 9
'Dönemin rengini değiştir
TxtAktar = "| " & Donem & " | " 'Dönemi mavi yap
Set myRange = objDoc.Sections(1).Headers(1).Range
myRange.Find.Execute FindText:=TxtAktar
myRange.Font.TextColor = RGB(51, 94, 163)
'Header'i sağa yasla
myRange.Paragraphs.Alignment = wdAlignParagraphRight

'_____

'Pane kapat (BİTİŞ)
objDoc.ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
'___________________________________________


'Dönem (Kapak sayfası dönemi güncelle)
objDoc.Tables(1).Cell(Row:=5, Column:=1).Range.Text = Donem

kaynak = "Kaynak: ishakkutlu.com"
'songozlem = "Son Gözlem: 31.12.2021"

Worksheets(15).Activate
Worksheets(15).ChartObjects("Chart 1").Chart.ChartArea.Copy
objDoc.Tables(4).Select
objDoc.Tables(4).Cell(2, 1).Range.PasteSpecial Link:=False, DataType:=wdPasteShape, Placement:=wdInLine, DisplayAsIcon:=False
objDoc.Tables(4).Cell(Row:=3, Column:=1).Range.Text = kaynak
objDoc.Tables(4).Cell(Row:=3, Column:=2).Range.Text = "Son Gözlem: " & Format(Worksheets(6).Range("B" & SayAralik), "dd.mm.yyyy")

Worksheets(15).ChartObjects("Chart 2").Chart.ChartArea.Copy
objDoc.Tables(4).Select
objDoc.Tables(4).Cell(2, 3).Range.PasteSpecial Link:=False, DataType:=wdPasteShape, Placement:=wdInLine, DisplayAsIcon:=False
objDoc.Tables(4).Cell(Row:=3, Column:=4).Range.Text = kaynak
objDoc.Tables(4).Cell(Row:=3, Column:=5).Range.Text = "Son Gözlem: " & Format(Worksheets(6).Range("J" & SayAralik), "dd.mm.yyyy")

Worksheets(15).ChartObjects("Chart 3").Chart.ChartArea.Copy
objDoc.Tables(6).Select
objDoc.Tables(6).Cell(2, 1).Range.PasteSpecial Link:=False, DataType:=wdPasteShape, Placement:=wdInLine, DisplayAsIcon:=False
objDoc.Tables(6).Cell(Row:=3, Column:=1).Range.Text = kaynak
objDoc.Tables(6).Cell(Row:=3, Column:=2).Range.Text = "Son Gözlem: " & Format(Worksheets(13).Range("B" & SayAralik), "dd.mm.yyyy")

Worksheets(15).ChartObjects("Chart 4").Chart.ChartArea.Copy
objDoc.Tables(6).Select
objDoc.Tables(6).Cell(2, 3).Range.PasteSpecial Link:=False, DataType:=wdPasteShape, Placement:=wdInLine, DisplayAsIcon:=False
objDoc.Tables(6).Cell(Row:=3, Column:=4).Range.Text = kaynak
objDoc.Tables(6).Cell(Row:=3, Column:=5).Range.Text = "Son Gözlem: " & Format(Worksheets(13).Range("J" & SayAralik), "dd.mm.yyyy")

Worksheets(15).ChartObjects("Chart 5").Chart.ChartArea.Copy
objDoc.Tables(8).Select
objDoc.Tables(8).Cell(2, 1).Range.PasteSpecial Link:=False, DataType:=wdPasteShape, Placement:=wdInLine, DisplayAsIcon:=False
objDoc.Tables(8).Cell(Row:=3, Column:=1).Range.Text = kaynak
objDoc.Tables(8).Cell(Row:=3, Column:=2).Range.Text = "Son Gözlem: " & Format(Worksheets(13).Range("R" & SayAralik), "dd.mm.yyyy")

Worksheets(15).ChartObjects("Chart 6").Chart.ChartArea.Copy
objDoc.Tables(10).Select
objDoc.Tables(10).Cell(2, 1).Range.PasteSpecial Link:=False, DataType:=wdPasteShape, Placement:=wdInLine, DisplayAsIcon:=False
objDoc.Tables(10).Cell(Row:=3, Column:=1).Range.Text = kaynak
objDoc.Tables(10).Cell(Row:=3, Column:=2).Range.Text = "Son Gözlem: " & Format(Worksheets(14).Range("B" & SayAralik), "dd.mm.yyyy")

Worksheets(15).ChartObjects("Chart 7").Chart.ChartArea.Copy
objDoc.Tables(10).Select
objDoc.Tables(10).Cell(2, 3).Range.PasteSpecial Link:=False, DataType:=wdPasteShape, Placement:=wdInLine, DisplayAsIcon:=False
objDoc.Tables(10).Cell(Row:=3, Column:=4).Range.Text = kaynak
objDoc.Tables(10).Cell(Row:=3, Column:=5).Range.Text = "Son Gözlem: " & Format(Worksheets(14).Range("J" & SayAralik), "dd.mm.yyyy")

Worksheets(15).ChartObjects("Chart 8").Chart.ChartArea.Copy
objDoc.Tables(11).Select
objDoc.Tables(11).Cell(2, 1).Range.PasteSpecial Link:=False, DataType:=wdPasteShape, Placement:=wdInLine, DisplayAsIcon:=False
objDoc.Tables(11).Cell(Row:=3, Column:=1).Range.Text = kaynak
objDoc.Tables(11).Cell(Row:=3, Column:=2).Range.Text = "Son Gözlem: " & Format(Worksheets(14).Range("R" & SayAralik), "dd.mm.yyyy")

Worksheets(15).ChartObjects("Chart 9").Chart.ChartArea.Copy
objDoc.Tables(13).Select
objDoc.Tables(13).Cell(2, 1).Range.PasteSpecial Link:=False, DataType:=wdPasteShape, Placement:=wdInLine, DisplayAsIcon:=False
objDoc.Tables(13).Cell(Row:=3, Column:=1).Range.Text = kaynak
objDoc.Tables(13).Cell(Row:=3, Column:=2).Range.Text = "Son Gözlem: " & Format(Worksheets(10).Range("B" & SayAralik), "dd.mm.yyyy")

Worksheets(15).ChartObjects("Chart 10").Chart.ChartArea.Copy
objDoc.Tables(15).Select
objDoc.Tables(15).Cell(2, 1).Range.PasteSpecial Link:=False, DataType:=wdPasteShape, Placement:=wdInLine, DisplayAsIcon:=False
objDoc.Tables(15).Cell(Row:=3, Column:=1).Range.Text = kaynak
objDoc.Tables(15).Cell(Row:=3, Column:=2).Range.Text = "Son Gözlem: " & Format(Worksheets(9).Range("B" & SayAralik), "dd.mm.yyyy")

'__________________

'TABLOLAR
'Y Firmasının Siparişleri
'Tabloya satır ekle
If SayAralik - IlkSatir > 0 Then
    With objDoc.Tables(16).Tables(1)
        X = 0
        For i = 1 To SayAralik - IlkSatir 'Gerekliyse tabloya satır ekle
            .Rows.Add BeforeRow:=objDoc.Tables(16).Tables(1).Rows(2) 'İç içe yuvalanmış tablo örneği
            X = X + 1
        Next i
        'Tabloya yaz
        m = 0
        For i = 1 To X + 1
            objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=1).Range.Text = Format(Worksheets(9).Cells(IlkSatir + m, 2).Value, "mmmm yyyy")
            'Bir hücrenin değeri 0 veya boş iken onun raporda yer alan tablodaki satırına 0 yazılır.
            If Worksheets(9).Cells(IlkSatir + m, 3).Value > 0 Then
                objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=2).Range.Text = Format(Worksheets(9).Cells(IlkSatir + m, 3).Value, "#,###") 'bindelik ayraç kullan
            Else
                objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=2).Range.Text = 0
            End If
            If Worksheets(9).Cells(IlkSatir + m, 4).Value > 0 Then
                objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=3).Range.Text = Format(Worksheets(9).Cells(IlkSatir + m, 4).Value, "#,###") 'bindelik ayraç kullan
            Else
                objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=3).Range.Text = 0
            End If
            If Worksheets(9).Cells(IlkSatir + m, 5).Value > 0 Then
                objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=4).Range.Text = Format(Worksheets(9).Cells(IlkSatir + m, 5).Value, "#,###") 'bindelik ayraç kullan
            Else
                objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=4).Range.Text = 0
            End If
            If Worksheets(9).Cells(IlkSatir + m, 6).Value > 0 Then
                objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=5).Range.Text = Format(Worksheets(9).Cells(IlkSatir + m, 6).Value, "#,###") 'bindelik ayraç kullan
            Else
                objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=5).Range.Text = 0
            End If
            If Worksheets(9).Cells(IlkSatir + m, 7).Value > 0 Then
                objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=6).Range.Text = Format(Worksheets(9).Cells(IlkSatir + m, 7).Value, "#,###") 'bindelik ayraç kullan
            Else
                objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=6).Range.Text = 0
            End If
            If Worksheets(9).Cells(IlkSatir + m, 8).Value > 0 Then
                objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=7).Range.Text = Format(Worksheets(9).Cells(IlkSatir + m, 8).Value, "#,###") 'bindelik ayraç kullan
            Else
                objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=7).Range.Text = 0
            End If
            
'            'Bir hücrenin değeri 0 veya boş iken onun raporda yer alan tablodaki satırına hiçbir değer yazılmaz.
'            objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=2).Range.Text = Format(Worksheets(9).Cells(IlkSatir + m, 3).Value, "#,###") 'bindelik ayraç kullan
'            objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=3).Range.Text = Format(Worksheets(9).Cells(IlkSatir + m, 4).Value, "#,###")
'            objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=4).Range.Text = Format(Worksheets(9).Cells(IlkSatir + m, 5).Value, "#,###")
'            objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=5).Range.Text = Format(Worksheets(9).Cells(IlkSatir + m, 6).Value, "#,###")
'            objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=6).Range.Text = Format(Worksheets(9).Cells(IlkSatir + m, 7).Value, "#,###")
'            objDoc.Tables(16).Tables(1).Cell(Row:=i + 1, Column:=7).Range.Text = Format(Worksheets(9).Cells(IlkSatir + m, 8).Value, "#,###")
            
            m = m + 1
        Next i
    End With
End If
objDoc.Tables(16).Cell(Row:=3, Column:=1).Range.Text = kaynak
objDoc.Tables(16).Cell(Row:=3, Column:=2).Range.Text = "Son Gözlem: " & Format(Worksheets(9).Range("B" & SayAralik), "dd.mm.yyyy")

'__________

'Raporun metinlerini oluştur.
objDoc.Tables(3).Cell(Row:=1, Column:=1).Range.Text = "Aşağıda " & DonemIlk & " ile " & DonemSon & " dönemleri içinde, X ve Y firmalarının ürün bazında toplam satış miktarları sunulmuştur (Grafik 1-2)."
TxtAktar = DonemIlk & " ile " & DonemSon
Set myRange = objDoc.Tables(3).Cell(Row:=1, Column:=1).Range
myRange.Find.Execute FindText:=TxtAktar
myRange.Font.Italic = True

TxtAktar = "ürün bazında"
Set myRange = objDoc.Tables(3).Cell(Row:=1, Column:=1).Range
myRange.Find.Execute FindText:=TxtAktar
myRange.Font.Italic = True

'''''
objDoc.Tables(5).Cell(Row:=1, Column:=1).Range.Text = DonemIlk & " ile " & DonemSon & " dönemleri içinde X ve Y firmalarının yurt içi ve dışı satış payları ile satış miktarları sunulmuştur (Grafik 3-4)."
TxtAktar = DonemIlk & " ile " & DonemSon
Set myRange = objDoc.Tables(5).Cell(Row:=1, Column:=1).Range
myRange.Find.Execute FindText:=TxtAktar
myRange.Font.Italic = True

TxtAktar = "satış payları"
Set myRange = objDoc.Tables(5).Cell(Row:=1, Column:=1).Range
myRange.Find.Execute FindText:=TxtAktar
myRange.Font.Italic = True

TxtAktar = "satış miktarları"
Set myRange = objDoc.Tables(5).Cell(Row:=1, Column:=1).Range
myRange.Find.Execute FindText:=TxtAktar
myRange.Font.Italic = True

'''''
objDoc.Tables(7).Cell(Row:=1, Column:=1).Range.Text = "Aşağıda ise " & DonemIlk & " ile " & DonemSon & " dönemleri içinde X ve Y firmalarının (yurt içi ve dışı satışlarının konsolide edildiği) toplam satış payları ile satış miktarları sunulmuştur (Grafik 5)."
TxtAktar = DonemIlk & " ile " & DonemSon
Set myRange = objDoc.Tables(7).Cell(Row:=1, Column:=1).Range
myRange.Find.Execute FindText:=TxtAktar
myRange.Font.Italic = True

''İmleci alta kaydır
'objDoc.Tables(7).Cell(Row:=1, Column:=1).Range.InsertBefore vbCr
'objDoc.Tables(7).Cell(Row:=1, Column:=1).Range.InsertBefore vbCr

'''''
objDoc.Tables(9).Cell(Row:=1, Column:=1).Range.Text = DonemIlk & " ile " & DonemSon & " dönemleri içinde X firması ile Y şubelerinin yurt içi ve dışı satış payları ile satış miktarları ve toplam satışlar içindeki payları sunulmuştur (Grafik 6-7-8)."
TxtAktar = DonemIlk & " ile " & DonemSon
Set myRange = objDoc.Tables(9).Cell(Row:=1, Column:=1).Range
myRange.Find.Execute FindText:=TxtAktar
myRange.Font.Italic = True

'Dipnot ekle
Set myRange = objDoc.Tables(9).Cell(1, 1).Range
myRange.Start = myRange.End - 2
myRange.End = myRange.End - 2
'myRange.Select
With myRange.FootnoteOptions
    .Location = wdBottomOfPage
    .NumberingRule = wdRestartContinuous
    .StartingNumber = 1
    .NumberStyle = wdNoteNumberStyleArabic
    '.LayoutColumns = 0
End With
TxtAktar = "Grafiklerde X firması ile Y firmasının Y1 ve Y2 şubelerine ilişkin payların toplamının %100'ü 1 puan aşması veya %100'den 1 puan düşük olması, oranların sadeleştirilmesi amacıyla ondalık hanelerin yukarı/aşağı yuvarlanmasından kaynaklanmaktadır."
myRange.Footnotes.Add Range:=myRange, Text:=TxtAktar

'''''
objDoc.Tables(12).Cell(Row:=1, Column:=1).Range.Text = DonemIlk & " ile " & DonemSon & " dönemleri içinde Y firmasının şubelerine ödenen aylık acenta ücretleri sunulmuştur (Grafik 9)."
TxtAktar = DonemIlk & " ile " & DonemSon
Set myRange = objDoc.Tables(12).Cell(Row:=1, Column:=1).Range
myRange.Find.Execute FindText:=TxtAktar
myRange.Font.Italic = True

TxtAktar = "aylık acenta ücretleri"
Set myRange = objDoc.Tables(12).Cell(Row:=1, Column:=1).Range
myRange.Find.Execute FindText:=TxtAktar
myRange.Font.Italic = True

objDoc.Tables(14).Cell(Row:=1, Column:=1).Range.Text = DonemIlk & " ile " & DonemSon & " dönemleri içinde Y acentasının siparişlerine ilişkin istatistikler ürün bazında ve adet olarak sunulmuştur (Grafik 10)."
TxtAktar = DonemIlk & " ile " & DonemSon
Set myRange = objDoc.Tables(14).Cell(Row:=1, Column:=1).Range
myRange.Find.Execute FindText:=TxtAktar
myRange.Font.Italic = True

'İmleci alta kaydır (Sayfa sonunda bölünen grafik/tabloları ayarlamak için)
objDoc.Tables(14).Cell(Row:=1, Column:=1).Range.InsertAfter vbCr
objDoc.Tables(14).Cell(Row:=1, Column:=1).Range.InsertAfter vbCr
objDoc.Tables(14).Cell(Row:=1, Column:=1).Range.InsertAfter vbCr
objDoc.Tables(14).Cell(Row:=1, Column:=1).Range.InsertAfter vbCr

'İçindkiler bölümünü güncelle
objDoc.TablesOfContents(1).UpdatePageNumbers

objWord.Visible = True


GoTo Son

SablondaTabloEksik:
'Word dosyasını ve wordu kapat
objDoc.Close SaveChanges:=False
objWord.Quit SaveChanges:=True
Set objWord = Nothing
Set objDoc = Nothing


Son:

Set objWord = Nothing
Set objDoc = Nothing
Application.CutCopyMode = False
Application.CutCopyMode = True

'Ana sayfaya git
Worksheets(17).Visible = True
Worksheets(17).Protect Password:="123"
Worksheets(17).Activate

For i = 1 To 3 'Dosyaları gizle
    Call UnprotectBook
    Worksheets(i).Visible = False
    Worksheets(i).Rows("13:17").Locked = True
    Worksheets(i).Protect Password:="123", AllowFormattingCells:=True, AllowFormattingColumns:=False, AllowFormattingRows:=True, AllowInsertingRows:=True, AllowDeletingRows:=True, AllowDeletingColumns:=True
Next i
For i = 4 To 5 'Dosyaları gizle
    Call UnprotectBook
    Worksheets(i).Visible = False
    Worksheets(i).Rows("14:17").Locked = True
    Worksheets(i).Protect Password:="123", AllowFormattingCells:=True, AllowFormattingColumns:=False, AllowFormattingRows:=True, AllowInsertingRows:=True, AllowDeletingRows:=True, AllowDeletingColumns:=True
Next i
For i = 6 To Worksheets.Count - 1 'Dosyaları gizle
    Call UnprotectBook
    Worksheets(i).Visible = False
    Worksheets(i).Protect Password:="123"
Next i
'On Error GoTo 0

Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.EnableEvents = True

Out:

Application.CutCopyMode = False
Application.CutCopyMode = True

ShtDelControl = False

End Sub

Not: Global değişkenler String tipinde deklare edilmiş olmakla birlikte, aktarıldığı lokal değişkenler sayısal (yani Long tipinde) olduğu için VBA otomatik olarak string tipinde olan numaraları sayısala (yani Long tipine) çevirecektir.

Burada SayAralik değişkeni ile çok sık karşılaşacaksınız. SayAralik değişkeni ise yukarıdaki örnekten açıklanacak olursa Mayıs 2021 dönemi ile Kasım 2021 dönemi arasında yer alan verileri, 18. satırdan itibaren başka boş bir sayfaya yazmak isteseydik son satırın numarasının ne olması gerektiğini verir. Örneğe göre 31-25+18=24. Mayıs 2021 dönemi ile Kasım 2021 dönemi aralığındaki verileri, ilk satır numarası 18 olan boş bir sayfaya yazmak isteysedik, son verinin yazılacağı satırın numarasının 24 olması gerektiğini anlıyoruz.

Aşağıdaki ekran görüntüsünde tutar bazında girilen satış değerlerinin birim fiyatlarına bölünmesi ile yurt içi ve yurt dışı satış adetlerinin elde edilmesini ve sonuçların da farklı sayfalara yazdırılmasına ilişkin algoritmaları göreceksiniz.

Aşağıdaki ekran görüntüsünde ise yukarıda dönüştürülen ve işlenen verilerin grafiklere aktarılmasına ilişkin algoritmaları görebilirsiniz.

Artık raporlanacak döneme ilişkin verilerimiz ve grafiklerimiz Excel’de hazır. Bir önceki oluşturulan rapor açıksa onun kapatılması ve “Operasyon” klasörü içindeki dosyaların temizlenmesine ilişkin algoritmalar aşağıdadır. Daha sonra yeni bir taslak dosya “Operasyon” klasörü içine kopyalanacak, seçilen döneme göre Word dosyası yeniden adlandırılacak ve Excel’deki içerikler Word dosyasında bulunan tabloların indeks numaraları kullanılarak aktarılacaktır.

Takip eden satırlarda Word dosyasının üst bilgisinde yer alacak bilgilerin eklenmesi ve metin boyutu, rengi vb. özellikler açısından biçimlendirilmesi, metinlerin ve dipnotların yazdırılması, grafik görsellerinin akatarılması, son gözlem ve kaynak gibi bilgilerin tablo ve grafiklere ilave edilmesi, tablolara yeni satırlar eklenmesi ve onların biçimlendirilmesi, sayfa sonu sarkan tablo ve grafiklerin düzenlenmesi, içindekiler bölümünün hazırlanması ve sayfaların güncellenmesi gibi bir dizi işlemi gerçekleştiren algoritmalar yer almaktadır.

3.2. ModuleRibbon

Bu bölümde Excel’de oluşturulan “Raporlama Modülü” sekmesi altında yer alan bağlantılara ilişkin algoritmalar yer almaktadır. Örneğin Y2 Verileri ikonuna tıklanması durumunda ne olacağı ya da Raporlama Arayüzü ikonuna tıklanması durumunda ne olacağı gibi. Bu bölümde yer alan VBA kodları nispeten kolaylıkla anlaşılabilir olduğu için üzerinde durmuyorum.

Option Explicit
Dim WsIndex As Integer

Sub anasayfaribbon(Control As IRibbonControl)
Dim Ws As Worksheet, i As Integer

Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False

ThisWorkbook.Unprotect "123"

i = 0
Worksheets(17).Visible = True
For Each Ws In ThisWorkbook.Worksheets
    i = i + 1
    If i <> 17 Then
        Ws.Visible = False
    End If
Next Ws
ThisWorkbook.Worksheets(17).Activate

With ActiveWindow
    .DisplayHeadings = False
    .DisplayHorizontalScrollBar = False 'False 'True
    .DisplayVerticalScrollBar = False
End With
Application.DisplayFormulaBar = False
ActiveWindow.DisplayGridlines = False
ActiveWindow.ScrollColumn = 1
ActiveWindow.ScrollRow = 1

ActiveSheet.DisplayPageBreaks = False

ThisWorkbook.Protect "123"

Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True

End Sub
Sub SayfaDuzeni()
Dim Ws As Worksheet, i As Integer

Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False

ThisWorkbook.Unprotect "123"

i = 0
Worksheets(WsIndex).Visible = True
For Each Ws In ThisWorkbook.Worksheets
    i = i + 1
    If i <> WsIndex Then
        Ws.Visible = False
    End If
Next Ws
ThisWorkbook.Worksheets(WsIndex).Activate

With ActiveWindow
    .DisplayHeadings = False
    .DisplayHorizontalScrollBar = True
    .DisplayVerticalScrollBar = True
End With
Application.DisplayFormulaBar = False
ActiveWindow.DisplayGridlines = False

ActiveSheet.DisplayPageBreaks = False

ThisWorkbook.Protect "123"

Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True

End Sub

Sub xverileriribbon(Control As IRibbonControl)
WsIndex = 1
Call SayfaDuzeni
End Sub

Sub y1verileriribbon(Control As IRibbonControl)
WsIndex = 2
Call SayfaDuzeni
End Sub

Sub y2verileriribbon(Control As IRibbonControl)
WsIndex = 3
Call SayfaDuzeni
End Sub

Sub ysiparisverileriribbon(Control As IRibbonControl)
WsIndex = 4
Call SayfaDuzeni
End Sub

Sub yacentaucretiverileriribbon(Control As IRibbonControl)
WsIndex = 5
Call SayfaDuzeni
End Sub

Sub desktopribbon(Control As IRibbonControl)
Dim oWSH As Object, oShortcut As Object, sPathDeskTop As String
Dim AutoPath As String, NameFinder As String, DestTarget As String
Dim NameLen As Integer

Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False

NameLen = Len(ThisWorkbook.Name) - 5
NameFinder = Left(ThisWorkbook.Name, NameLen)
AutoPath = ThisWorkbook.Path
DestTarget = AutoPath & "\" & NameFinder & ".xlsm"

Set oWSH = CreateObject("WScript.Shell")
sPathDeskTop = oWSH.SpecialFolders("Desktop")
Set oShortcut = oWSH.CreateShortCut(sPathDeskTop & "\" & NameFinder & ".lnk")
With oShortcut
.TargetPath = DestTarget
.IconLocation = AutoPath & "\ModuleFiles\Logo" & "\rmlogo.ico, 0"
.Save
End With
Set oWSH = Nothing

MsgBox NameFinder & " için masaüstü kısayolu başarılı bir şekilde oluşturuldu. Masaüstünüzde oluşturulan kısayol yardımıyla modüle hızlı bir şekilde erişebilirsiniz.", vbOKOnly + vbInformation, "ishakkutlu.com"

Son:

Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True

End Sub

Sub yardimribbon(Control As IRibbonControl)
Yardim.Show vbModal 'ess
End Sub

Sub raporribbon(Control As IRibbonControl)

Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False

RaporlamaArayuzu.Show vbModal

Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True

End Sub

Sub ikribbon(Control As IRibbonControl)
Dim chromePath As String

On Error GoTo DefBrowser
chromePath = """C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"""
Shell (chromePath & " -url " & "https://ishakkutlu.com")
GoTo JumpingDefBrowser
DefBrowser:
On Error Resume Next
ThisWorkbook.FollowHyperlink ("https://ishakkutlu.com")
On Error GoTo 0
JumpingDefBrowser:

End Sub

Sub githubribbon(Control As IRibbonControl)
Dim chromePath As String

On Error GoTo DefBrowser
chromePath = """C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"""
Shell (chromePath & " -url " & "https://github.com/ishakkutlu")
GoTo JumpingDefBrowser
DefBrowser:
On Error Resume Next
ThisWorkbook.FollowHyperlink ("https://github.com/ishakkutlu")
On Error GoTo 0
JumpingDefBrowser:
End Sub

Excel’de “Raporlama Modülü” gibi ayrı bir menü oluşturmak xml dosyaları ile yapılmaktadır. Excel’e menü ya da sekme eklemek ile ilgili daha sonra ayrı bir makale hazırlamayı düşünüyorum. Bu yüzden bu makalede Excel’e yeni menü ya da sekme eklemek ile ilgili konuya girmeyeceğim.

3.3. ModuleScrollCombo ve ModuleScrollFrame

Bu modüllerin içinde hazır scriptler vardır. Bu scriptleri Google’da aratarak bulabilirsiniz. Ancak her zaman projenize doğrudan uygulama imkanı olmayabilir. Bu yüzden onları kurcalayıp scriptin nasıl çalıştığını anlamanız ve projenize uyarlamanız gerekebilir. Ancak yeni bir script yazmak için harcayacağınız muazzam zamana karşılık var olan scripleri kullanmanız size büyük bir zaman kazandırır. Programlama dünyasında verimli çalışabilmek için her algoritmayı kendinizin hazırlaması gerektiği gibi bir anlayış yoktur. Bu modüldeki scripler üzerinde daha önce az veya çok iyileştirme yaptığım için yeni projelerinizde de sorunsuz bir şekilde çalışacaktır diye tahmin ediyorum.

ModuleScrollCombo içindeki algoritmalar farenin tekerliğini hareket ettirerek bir açılır listede yer alan ögeleri aşağı ve yukarı  kaydırmanıza olanak tanır. Bu konuya “Raporlama Arayüzü”nde tekrar değineceğim.

Option Explicit

Type POINTAPI
    X As Long
    Y As Long
End Type

Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Type MSLLHOOKSTRUCT
    Pt As POINTAPI
    mouseData As Long
    flags As Long
    time As Long
    dwExtraInfo As Long
End Type

#If VBA7 Then
    #If Win64 Then
        Declare PtrSafe Function WindowFromPoint Lib "user32" (ByVal Point As LongPtr) As LongPtr
    #Else
        Declare PtrSafe Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As LongPtr
    #End If
    Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
    Declare PtrSafe Function GetParent Lib "user32" (ByVal hWnd As LongPtr) As LongPtr
    Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
    Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As LongPtr)
    Declare PtrSafe Function GetCursorPos Lib "user32" (ByRef lpPoint As POINTAPI) As LongPtr
    Declare PtrSafe Function SetFocus Lib "user32" (ByVal hWnd As LongPtr) As LongPtr
    Declare PtrSafe Function IsWindow Lib "user32" (ByVal hWnd As LongPtr) As Long
    Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As LongPtr, ByVal hmod As LongPtr, ByVal dwThreadId As Long) As LongPtr
    Declare PtrSafe Function CallNextHookEx Lib "user32" (ByVal hHook As LongPtr, ByVal nCode As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
    Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As LongPtr) As LongPtr
    Declare PtrSafe Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As Long
    Declare PtrSafe Function GetClientRect Lib "user32" (ByVal hWnd As LongPtr, lpRect As RECT) As Long
    Declare PtrSafe Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
    Dim hWnd As LongPtr, lMouseHook As LongPtr
#Else
'PtrSafe ilave edildi.
    Declare PtrSafe Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
    Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
    Declare PtrSafe Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
    Declare PtrSafe Function GetActiveWindow Lib "user32" () As Long
    Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    Declare PtrSafe Function GetCursorPos Lib "user32" (ByRef lpPoint As POINTAPI) As Long
    Declare PtrSafe Function SetFocus Lib "user32" (ByVal hWnd As Long) As Long
    Declare PtrSafe Function IsWindow Lib "user32" (ByVal hWnd As Long) As Long
    Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
    Declare PtrSafe Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Any) As Long
    Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
    Declare PtrSafe Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Declare PtrSafe Function GetClientRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long
    Declare PtrSafe Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
    Dim hWnd As Long, lMouseHook As Long
#End If

Const WH_MOUSE_LL = 14
Const WM_MOUSEWHEEL = &H20A
Const HC_ACTION = 0
Const WM_LBUTTONDOWN = &H201
Const WM_LBUTTONUP = &H202
Const MK_LBUTTON = &H1
Const SM_CXVSCROLL = 2


Sub SetComboBoxHook(ByVal Control As Object)
    Dim tPT As POINTAPI
    Dim sBuffer As String
    Dim lRet As Long
    
    If lMouseHook = 0 Then
        GetCursorPos tPT
        #If VBA7 And Win64 Then
            Dim lPt As LongPtr
            CopyMemory lPt, tPT, LenB(tPT)
            hWnd = WindowFromPoint(lPt)
        #Else
            hWnd = WindowFromPoint(tPT.X, tPT.Y)
        #End If
        sBuffer = Space(256)
        lRet = GetClassName(GetParent(hWnd), sBuffer, 256)
        If InStr(Left(sBuffer, lRet), "MdcPopup") Then
            SetFocus hWnd
            #If VBA7 Then
                lMouseHook = SetWindowsHookEx(WH_MOUSE_LL, AddressOf MouseProc, Application.HinstancePtr, 0)
            #Else
                lMouseHook = SetWindowsHookEx(WH_MOUSE_LL, AddressOf MouseProc, Application.Hinstance, 0)
            #End If
        End If
    End If
End Sub

Sub RemoveComboBoxHook()
    UnhookWindowsHookEx lMouseHook: lMouseHook = 0
End Sub


#If VBA7 Then
    Function MouseProc(ByVal nCode As Long, ByVal wParam As LongPtr, lParam As MSLLHOOKSTRUCT) As LongPtr
#Else
    Function MouseProc(ByVal nCode As Long, ByVal wParam As Long, lParam As MSLLHOOKSTRUCT) As Long
#End If

    Dim sBuffer As String
    Dim lRet As Long
    Dim tRect As RECT
        
    sBuffer = Space(256)
    lRet = GetClassName(GetActiveWindow, sBuffer, 256)
    If Left(sBuffer, lRet) = "wndclass_desked_gsk" Then Call RemoveComboBoxHook
    If IsWindow(hWnd) = 0 Then Call RemoveComboBoxHook
    
    If (nCode = HC_ACTION) Then
        If wParam = WM_MOUSEWHEEL Then
            #If VBA7 And Win64 Then
                Dim lPt As LongPtr
                Dim Low As Integer, High As Integer
                Dim lParm As LongPtr
                CopyMemory lPt, lParam.Pt, LenB(lPt)
                If WindowFromPoint(lPt) = hWnd Then
            #Else
                Dim Low As Integer, High As Integer
                Dim lParm As Long
                If WindowFromPoint(lParam.Pt.X, lParam.Pt.Y) = hWnd Then
            #End If
                    GetClientRect hWnd, tRect
                    If lParam.mouseData > 0 Then
                        Low = tRect.Right - (GetSystemMetrics(SM_CXVSCROLL) / 2)
                        High = tRect.Top + ((GetSystemMetrics(SM_CXVSCROLL) / 2) + 1)
                        lParm = MakeDWord(Low, High)
                    Else
                        Low = tRect.Right - (GetSystemMetrics(SM_CXVSCROLL) / 2)
                        High = tRect.Bottom - ((GetSystemMetrics(SM_CXVSCROLL) / 2) + 1)
                        lParm = MakeDWord(Low, High)
                    End If
                    PostMessage hWnd, WM_LBUTTONDOWN, MK_LBUTTON, lParm
                    PostMessage hWnd, WM_LBUTTONUP, MK_LBUTTON, lParm
            End If
        End If
    End If
    
    MouseProc = CallNextHookEx(lMouseHook, nCode, wParam, ByVal lParam)
End Function


Private Function MakeDWord(ByVal LoWord As Integer, ByVal HiWord As Integer) As Long
    MakeDWord = (HiWord * &H10000) Or (LoWord And &HFFFF&)
End Function

ModuleScrollFrame içindeki algoritmalar ise (yukarıdaki sürece benzer şekilde) farenin tekerliğini hareket ettirerek bir frame’i aşağı ve yukarı kaydırmanıza olanak tanır. Bu konuya ise “Yardım” bölümünde tekrar değineceğim.

Option Explicit

#If Win64 Then
    Private Type POINTAPI
       XY As LongLong
    End Type
#Else
    Private Type POINTAPI
           X As Long
           Y As Long
    End Type
#End If

Private Type MOUSEHOOKSTRUCT
    Pt As POINTAPI
    hWnd As Long
    wHitTestCode As Long
    dwExtraInfo As Long
End Type

#If VBA7 Then
    Private Declare PtrSafe Function FindWindow Lib "user32" _
                                            Alias "FindWindowA" ( _
                                                            ByVal lpClassName As String, _
                                                            ByVal lpWindowName As String) As LongPtr ' not sure if this should be LongPtr
    #If Win64 Then
        Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" _
                                            Alias "GetWindowLongPtrA" ( _
                                                            ByVal hWnd As LongPtr, _
                                                            ByVal nIndex As Long) As LongPtr
    #Else
        Private Declare PtrSafe Function GetWindowLong Lib "user32" _
                                            Alias "GetWindowLongA" ( _
                                                            ByVal hWnd As LongPtr, _
                                                            ByVal nIndex As Long) As LongPtr
    #End If
    Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" _
                                            Alias "SetWindowsHookExA" ( _
                                                            ByVal idHook As Long, _
                                                            ByVal lpfn As LongPtr, _
                                                            ByVal hmod As LongPtr, _
                                                            ByVal dwThreadId As Long) As LongPtr
    Private Declare PtrSafe Function CallNextHookEx Lib "user32" ( _
                                                            ByVal hHook As LongPtr, _
                                                            ByVal nCode As Long, _
                                                            ByVal wParam As LongPtr, _
                                                           lParam As Any) As LongPtr
    Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" ( _
                                                            ByVal hHook As LongPtr) As LongPtr ' MAYBE Long
    'Private Declare PtrSafe Function PostMessage Lib "user32.dll" _
    '                                         Alias "PostMessageA" ( _
    '                                                         ByVal hwnd As LongPtr, _
    '                                                         ByVal wMsg As Long, _
    '                                                         ByVal wParam As LongPtr, _
    '                                                         ByVal lParam As LongPtr) As LongPtr   ' MAYBE Long
    #If Win64 Then
        Private Declare PtrSafe Function WindowFromPoint Lib "user32" ( _
                                                            ByVal Point As LongLong) As LongPtr    '
    #Else
        Private Declare PtrSafe Function WindowFromPoint Lib "user32" ( _
                                                            ByVal xPoint As Long, _
                                                            ByVal yPoint As Long) As LongPtr    '
    #End If
    Private Declare PtrSafe Function GetCursorPos Lib "user32" ( _
                                                            ByRef lpPoint As POINTAPI) As LongPtr   'MAYBE Long
#Else 'PtrSafe ilave edildi.
    Private Declare PtrSafe Function FindWindow Lib "user32" _
                                            Alias "FindWindowA" ( _
                                                            ByVal lpClassName As String, _
                                                            ByVal lpWindowName As String) As Long
    Private Declare PtrSafe Function GetWindowLong Lib "user32.dll" _
                                            Alias "GetWindowLongA" ( _
                                                            ByVal hWnd As Long, _
                                                            ByVal nIndex As Long) As Long
    Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" _
                                            Alias "SetWindowsHookExA" ( _
                                                            ByVal idHook As Long, _
                                                            ByVal lpfn As Long, _
                                                            ByVal hmod As Long, _
                                                            ByVal dwThreadId As Long) As Long
    Private Declare PtrSafe Function CallNextHookEx Lib "user32" ( _
                                                            ByVal hHook As Long, _
                                                            ByVal nCode As Long, _
                                                            ByVal wParam As Long, _
                                                           lParam As Any) As Long
    Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" ( _
                                                            ByVal hHook As Long) As Long
    'Private Declare Function PostMessage Lib "user32.dll" _
    '                                         Alias "PostMessageA" ( _
    '                                                         ByVal hwnd As Long, _
    '                                                         ByVal wMsg As Long, _
    '                                                         ByVal wParam As Long, _
    '                                                         ByVal lParam As Long) As Long
    Private Declare PtrSafe Function WindowFromPoint Lib "user32" ( _
                                                            ByVal xPoint As Long, _
                                                            ByVal yPoint As Long) As Long
    Private Declare PtrSafe Function GetCursorPos Lib "user32.dll" ( _
                                                            ByRef lpPoint As POINTAPI) As Long
#End If

Private Const WH_MOUSE_LL As Long = 14
Private Const WM_MOUSEWHEEL As Long = &H20A
Private Const HC_ACTION As Long = 0
Private Const GWL_HINSTANCE As Long = (-6)
'Private Const WM_KEYDOWN As Long = &H100
'Private Const WM_KEYUP As Long = &H101
'Private Const VK_UP As Long = &H26
'Private Const VK_DOWN As Long = &H28
'Private Const WM_LBUTTONDOWN As Long = &H201
Dim n As Long
Private mCtl As Object
Private mbHook As Boolean

'******************************************
'******************************************
Const scrollOnly As Boolean = True ' set to False to actually move selection when scrolling mouse wheel
'******************************************
'******************************************

#If VBA7 Then
    Private mLngMouseHook As LongPtr
    Private mListBoxHwnd As LongPtr
#Else
    Private mLngMouseHook As Long
    Private mListBoxHwnd As Long
#End If
     
Sub HookListBoxScroll(frm As Object, ctl As Object)
' big thanks to Peter Thornton (https://social.msdn.microsoft.com/Forums/en-US/9255d7d6-0266-45aa-9589-7533bd82d591/need-help-with-macro-to-make-an-userform-able-to-scroll-with-a-mouse?forum=isvvba)
' as well as user 'Fhorst' for 64 bit conversion help.
' option for scrolling
    Dim tPT As POINTAPI
    #If VBA7 Then
        Dim lngAppInst As LongPtr
        Dim hwndUnderCursor As LongPtr
    #Else
        Dim lngAppInst As Long
        Dim hwndUnderCursor As Long
    #End If
    GetCursorPos tPT
    #If Win64 Then
        hwndUnderCursor = WindowFromPoint(tPT.XY)
    #Else
        hwndUnderCursor = WindowFromPoint(tPT.X, tPT.Y)
    #End If
    If TypeOf ctl Is UserForm Then
        If Not frm Is ctl Then
               ctl.SetFocus
        End If
    Else
        If Not frm.ActiveControl Is ctl Then
             ctl.SetFocus
        End If
    End If
    If mListBoxHwnd <> hwndUnderCursor Then
        UnhookListBoxScroll
        Set mCtl = ctl
        mListBoxHwnd = hwndUnderCursor
        #If Win64 Then
            lngAppInst = GetWindowLongPtr(mListBoxHwnd, GWL_HINSTANCE)
        #Else
            lngAppInst = GetWindowLong(mListBoxHwnd, GWL_HINSTANCE)
        #End If
        ' PostMessage mListBoxHwnd, WM_LBUTTONDOWN, 0&, 0&
        If Not mbHook Then
            mLngMouseHook = SetWindowsHookEx( _
                                            WH_MOUSE_LL, AddressOf MouseProc, lngAppInst, 0)
            mbHook = mLngMouseHook <> 0
        End If
    End If
End Sub

Sub UnhookListBoxScroll()
    If mbHook Then
        Set mCtl = Nothing
        UnhookWindowsHookEx mLngMouseHook
        mLngMouseHook = 0
        mListBoxHwnd = 0
        mbHook = False
    End If
End Sub
#If VBA7 Then
    Private Function MouseProc( _
                            ByVal nCode As Long, ByVal wParam As Long, _
                            ByRef lParam As MOUSEHOOKSTRUCT) As LongPtr
        Dim idx As Long
        On Error GoTo errH
        If (nCode = HC_ACTION) Then
            #If Win64 Then
                If WindowFromPoint(lParam.Pt.XY) = mListBoxHwnd Then
                    If wParam = WM_MOUSEWHEEL Then
                        MouseProc = True
'                        If lParam.hWnd > 0 Then
'                            postMessage mListBoxHwnd, WM_KEYDOWN, VK_UP, 0
'                        Else
'                            postMessage mListBoxHwnd, WM_KEYDOWN, VK_DOWN, 0
'                        End If
'                        postMessage mListBoxHwnd, WM_KEYUP, VK_UP, 0
                        If TypeOf mCtl Is Frame Then
                            If lParam.hWnd > 0 Then idx = -10 Else idx = 10
                            idx = idx + mCtl.ScrollTop
                            If idx >= 0 And idx < ((mCtl.ScrollHeight - mCtl.Height) + 17.25) Then
                                mCtl.ScrollTop = idx
                            End If
                        ElseIf TypeOf mCtl Is UserForm Then
                            If lParam.hWnd > 0 Then idx = -10 Else idx = 10
                            idx = idx + mCtl.ScrollTop
                            If idx >= 0 And idx < ((mCtl.ScrollHeight - mCtl.Height) + 17.25) Then
                                mCtl.ScrollTop = idx
                            End If
                        Else
                            If lParam.hWnd > 0 Then idx = -1 Else idx = 1
                            '*************** MAKE scrollOnly False IF YOU WANT TO CHANGE THE SELECTION RATHER THAN JUST SCROLL ******
                            If scrollOnly Then
                                idx = idx + mCtl.TopIndex
                                If idx >= 0 Then mCtl.TopIndex = idx
                            Else
                                idx = idx + mCtl.ListIndex
                                If idx >= 0 Then mCtl.ListIndex = idx
                            End If
                            '*********************************************************************************************************
                        End If
                    Exit Function
                    End If
                Else
                    UnhookListBoxScroll
                End If
            #Else
                If WindowFromPoint(lParam.Pt.X, lParam.Pt.Y) = mListBoxHwnd Then
                    If wParam = WM_MOUSEWHEEL Then
                        MouseProc = True
'                        If lParam.hWnd > 0 Then
'                            postMessage mListBoxHwnd, WM_KEYDOWN, VK_UP, 0
'                        Else
'                            postMessage mListBoxHwnd, WM_KEYDOWN, VK_DOWN, 0
'                        End If
'                        postMessage mListBoxHwnd, WM_KEYUP, VK_UP, 0
                        If TypeOf mCtl Is Frame Then
                            If lParam.hWnd > 0 Then idx = -10 Else idx = 10
                            idx = idx + mCtl.ScrollTop
                            If idx >= 0 And idx < ((mCtl.ScrollHeight - mCtl.Height) + 17.25) Then
                                mCtl.ScrollTop = idx
                            End If
                        ElseIf TypeOf mCtl Is UserForm Then
                            If lParam.hWnd > 0 Then idx = -10 Else idx = 10
                            idx = idx + mCtl.ScrollTop
                            If idx >= 0 And idx < ((mCtl.ScrollHeight - mCtl.Height) + 17.25) Then
                                mCtl.ScrollTop = idx
                            End If
                        Else
                            If lParam.hWnd > 0 Then idx = -1 Else idx = 1
                            '*************** MAKE scrollOnly False IF YOU WANT TO CHANGE THE SELECTION RATHER THAN JUST SCROLL ******
                            If scrollOnly Then
                                idx = idx + mCtl.TopIndex
                                If idx >= 0 Then mCtl.TopIndex = idx
                            Else
                                idx = idx + mCtl.ListIndex
                                If idx >= 0 Then mCtl.ListIndex = idx
                            End If
                            '*********************************************************************************************************
                        End If
                        Exit Function
                    End If
                Else
                    UnhookListBoxScroll
                End If
            #End If
        End If
        MouseProc = CallNextHookEx( _
                                mLngMouseHook, nCode, wParam, ByVal lParam)
        Exit Function
errH:
        UnhookListBoxScroll
    End Function
#Else
    Private Function MouseProc( _
                            ByVal nCode As Long, ByVal wParam As Long, _
                            ByRef lParam As MOUSEHOOKSTRUCT) As Long
        Dim idx As Long
        On Error GoTo errH
        If (nCode = HC_ACTION) Then
            If WindowFromPoint(lParam.Pt.X, lParam.Pt.Y) = mListBoxHwnd Then
                If wParam = WM_MOUSEWHEEL Then
                    MouseProc = True
'                    If lParam.hWnd > 0 Then
'                    postMessage mListBoxHwnd, WM_KEYDOWN, VK_UP, 0
'                    Else
'                    postMessage mListBoxHwnd, WM_KEYDOWN, VK_DOWN, 0
'                    End If
'                    postMessage mListBoxHwnd, WM_KEYUP, VK_UP, 0
                   
                    If TypeOf mCtl Is Frame Then
                        If lParam.hWnd > 0 Then idx = -10 Else idx = 10
                        idx = idx + mCtl.ScrollTop
                        If idx >= 0 And idx < ((mCtl.ScrollHeight - mCtl.Height) + 17.25) Then
                            mCtl.ScrollTop = idx
                        End If
                    ElseIf TypeOf mCtl Is UserForm Then
                        If lParam.hWnd > 0 Then idx = -10 Else idx = 10
                        idx = idx + mCtl.ScrollTop
                        If idx >= 0 And idx < ((mCtl.ScrollHeight - mCtl.Height) + 17.25) Then
                            mCtl.ScrollTop = idx
                        End If
                    Else
                        If lParam.hWnd > 0 Then idx = -1 Else idx = 1
                        '*************** MAKE scrollOnly False IF YOU WANT TO CHANGE THE SELECTION RATHER THAN JUST SCROLL ******
                        If scrollOnly Then
                            idx = idx + mCtl.TopIndex
                            If idx >= 0 Then mCtl.TopIndex = idx
                        Else
                            idx = idx + mCtl.ListIndex
                            If idx >= 0 Then mCtl.ListIndex = idx
                        End If
                        '*********************************************************************************************************
                    End If
                    Exit Function
                End If
            Else
                UnhookListBoxScroll
            End If
        End If
        MouseProc = CallNextHookEx( _
        mLngMouseHook, nCode, wParam, ByVal lParam)
        Exit Function
errH:
        UnhookListBoxScroll
    End Function
#End If

3.4. ModuleSystem

Bu modül içinde ise word dosyasının açık olup olmadığını anlayan algoritmalar ile çalışma kitabının kilitidini açan basit bir prosedür yer almaktadır. Çalışma kitabının kilidini açan prosedür, (çalışma kitabının kilidi açık olsa bile) başka prosedürler ile senkronize çalışarak kullanıcının yanlışlıkla bir sayfayı silmeye çalışması durumunda onu engelleyen, yani sayfanın silinmesini engelleyen bir veri güvenliği algoritmasıdır. Örneğin Sheet1, Sheet2 gibi objelere çift tıklarsanız Worksheet_Deactivate() prosedürlerini görürsünüz. Siz o sayfayı silmeye çalıştığınızda sayfa deaktive olmaya hazırlandığı için ilgili sayfada gördüğünüz kodlar tetiklenerek çalışma kitabını kilitleyecek, dolayısıyla çalışma kitabı kilitli olan bir dosyadan da sayfa silinemeyeceği için sayfanın silinmesi engellenecektir. Bu işlemi engelledikten hemen sonra Worksheet_Deactivate() prosedürü, çalışma kitabının kilidini tekrar açarak çalışma kitabını başlangıç durumuna geri döndürmüş olacaktır.

Public OpenWordTakip As Boolean

Sub OpenWordControl()

Dim ObjWordx As Object

'MsgBox "OpenWordControl prosedürü başlıyor."

    On Error GoTo NoOpenDoc
    Set ObjWordx = GetObject(, "Word.Application")
    Set ObjWordx = GetObject(, "Word.Application")
    Set ObjWordx = GetObject(, "Word.Application")
    Set ObjWordx = GetObject(, "Word.Application")
    Set ObjWordx = GetObject(, "Word.Application")
    OpenWordTakip = True
    GoTo NoOpenDocAtla
NoOpenDoc:
    OpenWordTakip = False
NoOpenDocAtla:
    If OpenWordTakip = True Then
        'MsgBox ObjWordx.ActiveDocument.Name
        If ObjWordx.ActiveDocument.Name <> "" Then
            ObjWordx.Quit SaveChanges:=True
            'MsgBox "Dosya OpenWordControl methodu ile kapatıldı."
            
        End If
    Else
        'MsgBox "Açık word dokümanı yok."
    End If

Son:
Set ObjWordx = Nothing
'Application.Wait (Now + TimeValue("00:00:03"))

End Sub

Function IsFileOpen(FileName As String)
    Dim ff As Long, ErrNo As Long

    On Error Resume Next
    ff = FreeFile()
    Open FileName For Input Lock Read As #ff
    Close ff
    ErrNo = Err
    On Error GoTo 0

    Select Case ErrNo
    Case 0:    IsFileOpen = False
    Case 70:   IsFileOpen = True
    Case 53:   GoTo Son
    Case Else: Error ErrNo
    End Select
Son:
End Function

Sub UnprotectBook()
ThisWorkbook.Unprotect "123"
End Sub

Aşağıdaki kodlar ise Sheet1′ e ait örnek kodlardır.

Option Explicit
Private Sub Worksheet_Deactivate()
If ActiveSheet.Index = 1 Then
    ThisWorkbook.Protect "123", True
    Application.OnTime Now, "UnprotectBook"
End If
End Sub

Sheet2′ ye ait örnek kodlar ise şu şekildedir.

Option Explicit

Private Sub Worksheet_Deactivate()
If ActiveSheet.Index = 2 Then
    ThisWorkbook.Protect "123", True
    Application.OnTime Now, "UnprotectBook"
End If
End Sub

3.5. ThisWorkbook

Bu bölümde ise çalışma kitabı kapanmadan önce kendisini (yani çalışma kitabını) otomatik olarak kaydeden basit bir prosedür ile açılış esnasında belirli işlemleri ve kontrolleri yapan algoritmalar yer almaktadır.

Workbook_Open() prosedürü öncelikle ModuleFiles klasörü ile Excel dosyasının aynı dizinde olup olmadığını kontrol eder. Aynı dizinde değilse kullanıcıya bir uyarı mesajı verir. Modül açılacaktır, ancak raporlama işlemini çalıştırmak istediğinizde size tekrar uyarı gönderip işlemi gerçekleştirmeyecektir. Bu bölümde sayfaların gizlenmesi ve kilitleri açık kaldıysa tekrar kilinmesi, çalışma kitabının kilitlenmesi, ana sayfanın açılış sayfası olması, ana sayfada başlıklar, kılavuz çizgileri ve formül barı ile yatay ve dikey kaydırma çubuklarının gizlenmesi, sayfa yazdırma işaretçilerinin gizlenmesi ile yatay ve dikey kaydırma çubuklarının sıfırlanması; yani dikey kaydırma çubuğunun en üstte, yatay kaydırma çubuğunun en solda olacak şekilde ayarlanması gibi bir dizi işlem gerçekleştirilir.

Option Explicit

Private Sub Workbook_BeforeClose(Cancel As Boolean)

On Error Resume Next
ThisWorkbook.Save

End Sub
Private Sub Workbook_Open()
Dim i As Integer, AutoPath As String

If ThisWorkbook.ReadOnly = True Then
    MsgBox "Bu dosya doğrudan mailden açılamaz. Lütfen dosyayı bilgisayarınıza indirip tekrar deneyiniz.", vbOKOnly + vbExclamation, "ishakkutlu.com"
    ThisWorkbook.Close SaveChanges:=False
    GoTo Son
End If

'Pathfinder...
AutoPath = ThisWorkbook.Path
'ModuleFiles klasör adını kontrol et.
If Not Dir(AutoPath & "\ModuleFiles\", vbDirectory) <> vbNullString Then
    MsgBox AutoPath & "\ModuleFiles\" & " dizinine ulaşılamıyor. Bu dizine ait ModuleFiles isimli klasörün adında değişiklik yapılmış, ModuleFiles isimli klasör silinmiş veya Raporlama App isimli uygulama dosyası ModuleFiles isimli klasörden farklı bir dizinde olabilir.", vbOKOnly + vbCritical, "ishakkutlu.com"
    GoTo Son
End If

Application.ScreenUpdating = False
Application.DisplayAlerts = False


Application.EnableEvents = False
Application.EnableEvents = True

'On Error Resume Next
ThisWorkbook.Unprotect "123"

Worksheets(17).Visible = True
Worksheets(17).Protect Password:="123"
Worksheets(17).Activate

For i = 1 To 3 'Dosyaları gizle
    Call UnprotectBook
    Worksheets(i).Visible = False
    Worksheets(i).Unprotect Password:="123"
    Worksheets(i).Rows("13:17").Locked = True
    Worksheets(i).Protect Password:="123", AllowFormattingCells:=True, AllowFormattingColumns:=False, AllowFormattingRows:=True, AllowInsertingRows:=True, AllowDeletingRows:=True, AllowDeletingColumns:=True
Next i
For i = 4 To 5 'Dosyaları gizle
    Call UnprotectBook
    Worksheets(i).Visible = False
    Worksheets(i).Unprotect Password:="123"
    Worksheets(i).Rows("14:17").Locked = True
    Worksheets(i).Protect Password:="123", AllowFormattingCells:=True, AllowFormattingColumns:=False, AllowFormattingRows:=True, AllowInsertingRows:=True, AllowDeletingRows:=True, AllowDeletingColumns:=True
Next i
For i = 6 To Worksheets.Count - 1 'Dosyaları gizle
    Call UnprotectBook
    Worksheets(i).Unprotect Password:="123"
    Worksheets(i).Visible = False
    Worksheets(i).Protect Password:="123"
Next i

Worksheets(17).Activate
With ActiveWindow
    .DisplayHeadings = False
    .DisplayHorizontalScrollBar = False
    .DisplayVerticalScrollBar = False
End With
Application.DisplayFormulaBar = False
ActiveWindow.DisplayGridlines = False

ActiveSheet.DisplayPageBreaks = False

ActiveWindow.ScrollColumn = 1
ActiveWindow.ScrollRow = 1

ThisWorkbook.Protect "123"

Application.DisplayAlerts = True
Application.ScreenUpdating = True

Son:

End Sub

3.6. RaporlamaArayuzu

Bu form ile kullanıcının görüntülediği raporlama arayüzü tasarlanmıştır. Bu arayüz hem görsel bakımdan hem de algoritmik bakımdan bir çalışma gerektirir. Örneğin butonları ve açılır listeleri konumlandırma birer görsel düzenlemedir. Konumlandırılan açılır listelerin ve butonların (bir butona tıklanması, bir açılır listeye tıklanması ya da farenin bir nesnenin (buton, etiket, frame vb.) üzerinde gezdirilmesi gibi) davranışlarını belirlemek ise algoritma yazmanızı gerektirir. Aşağıdaki ekran görüntüsünde işaretlendiği gibi “RaporlamaArayuzu” objesi üzerine gelip sağ tık yapar ve “View Code” sekmesine tıklarsanız, formun algoritmalarına ulaşırsınız.

Örneğin doğrudan “Raporla” butonunun prosedürüne erişmek isterseniz “Raporla” butonuna iki kez tıklamanız yeterli olacaktır.

Option Explicit


Sub ColorChangerGenel()

If Raporla.BackColor <> RGB(205, 205, 205) Then
Raporla.BackColor = RGB(205, 205, 205)
Raporla.ForeColor = &H80000012
End If

If Kapat.BackColor <> RGB(205, 205, 205) Then
Kapat.BackColor = RGB(205, 205, 205)
Kapat.ForeColor = &H80000012
End If

'BaslangicTarihi
'BaslangicTarihiFrame
If BaslangicTarihiFrame.BackColor <> RGB(200, 200, 200) Then
    BaslangicTarihiFrame.BackColor = RGB(200, 200, 200)
End If
'LblBaslangicTarihi
If LblBaslangicTarihi.BackColor <> &H80000004 Then
    LblBaslangicTarihi.BackColor = &H80000004
    LblBaslangicTarihi.ForeColor = &H80000012
End If

'BitisTarihi
'BitisTarihiFrame
If BitisTarihiFrame.BackColor <> RGB(200, 200, 200) Then
    BitisTarihiFrame.BackColor = RGB(200, 200, 200)
End If
'LblBitisTarihi
If LblBitisTarihi.BackColor <> &H80000004 Then
    LblBitisTarihi.BackColor = &H80000004
    LblBitisTarihi.ForeColor = &H80000012
End If


End Sub

Private Sub Raporla_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
Raporla.BackColor = RGB(26, 168, 212)
Raporla.ForeColor = RGB(255, 255, 255)
End Sub

Private Sub Kapat_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
Kapat.BackColor = RGB(26, 168, 212)
Kapat.ForeColor = RGB(255, 255, 255)
End Sub

'BaslangicTarihi color
Private Sub BaslangicTarihiFrame_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
BaslangicTarihiFrame.BackColor = RGB(26, 168, 212)
End Sub
Private Sub BaslangicTarihi_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
BaslangicTarihiFrame.BackColor = RGB(26, 168, 212)
Call SetComboBoxHook(BaslangicTarihi)
End Sub
Private Sub LblBaslangicTarihi_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
BaslangicTarihiFrame.BackColor = RGB(26, 168, 212)
End Sub
Private Sub BaslangicTarihi_LostFocus()
Call RemoveComboBoxHook
End Sub
Private Sub BaslangicTarihi_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Me.BaslangicTarihi.DropDown
End Sub
Private Sub BaslangicTarihi_Change()

If BaslangicTarihi.ListIndex = -1 And BaslangicTarihi.Value <> "" Then
   BaslangicTarihi.Value = ""
   GoTo Son
End If

If BaslangicTarihi.Value <> "" Then
    BaslangicTarihi.SelStart = 0
    BaslangicTarihi.SelLength = Len(BaslangicTarihi.Value)
End If

Son:

End Sub

'BitisTarihi Color
Private Sub BitisTarihiFrame_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
BitisTarihiFrame.BackColor = RGB(26, 168, 212)
End Sub
Private Sub BitisTarihi_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
BitisTarihiFrame.BackColor = RGB(26, 168, 212)
Call SetComboBoxHook(BitisTarihi)
End Sub
Private Sub LblBitisTarihi_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
BitisTarihiFrame.BackColor = RGB(26, 168, 212)
End Sub
Private Sub BitisTarihi_LostFocus()
Call RemoveComboBoxHook
End Sub
Private Sub BitisTarihi_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Me.BitisTarihi.DropDown
End Sub

Private Sub BitisTarihi_Change()

If BitisTarihi.ListIndex = -1 And BitisTarihi.Value <> "" Then
   BitisTarihi.Value = ""
   GoTo Son
End If

If BitisTarihi.Value <> "" Then
    BitisTarihi.SelStart = 0
    BitisTarihi.SelLength = Len(BitisTarihi.Value)
End If

Son:

End Sub

Private Sub UserForm_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
End Sub
Private Sub TasiyiciFrame_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
End Sub
Private Sub BaslikFrame_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
End Sub
Private Sub UstMenuFrame_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
End Sub
Private Sub BilgilendirmeFrame_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel

End Sub
Private Sub LblBilgilendirme_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
End Sub
Private Sub AltMenuFrame_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
End Sub

Private Sub Raporla_Click()
Dim DonemAraligi As Integer, Bilgi As Variant
Dim WsXFirma As Worksheet, IlkSatirBul As Range, SonSatirBul As Range
Dim Say As Long, i As Long

'Tarih formatı kontrol
ThisWorkbook.Unprotect "123"

Say = ThisWorkbook.Worksheets(1).Range("B" & Rows.Count).End(xlUp).Row
For i = Say To 18 Step -1
    If IsDate(ThisWorkbook.Worksheets(1).Range("B" & i).Value) = False Then
        MsgBox "X firmasının dönem verilerinde, tarih formatına uymayan en az bir veri tespit edildi. Lütfen ilgili veriyi düzeltip tekrar deneyiniz.", vbOKOnly + vbExclamation, "ishakkutlu.com"
        GoTo Son
    End If
Next i
For i = Say To 18 Step -1
    If IsDate(ThisWorkbook.Worksheets(1).Range("J" & i).Value) = False Then
        MsgBox "X firmasının dönem verilerinde, tarih formatına uymayan en az bir veri tespit edildi. Lütfen ilgili veriyi düzeltip tekrar deneyiniz.", vbOKOnly + vbExclamation, "ishakkutlu.com"
        GoTo Son
    End If
Next i
Say = ThisWorkbook.Worksheets(2).Range("B" & Rows.Count).End(xlUp).Row
For i = Say To 18 Step -1
    If IsDate(ThisWorkbook.Worksheets(2).Range("B" & i).Value) = False Then
        MsgBox "Y1 şubesinin dönem verilerinde, tarih formatına uymayan en az bir veri tespit edildi. Lütfen ilgili veriyi düzeltip tekrar deneyiniz.", vbOKOnly + vbExclamation, "ishakkutlu.com"
        GoTo Son
    End If
Next i
For i = Say To 18 Step -1
    If IsDate(ThisWorkbook.Worksheets(2).Range("J" & i).Value) = False Then
        MsgBox "Y1 şubesinin dönem verilerinde, tarih formatına uymayan en az bir veri tespit edildi. Lütfen ilgili veriyi düzeltip tekrar deneyiniz.", vbOKOnly + vbExclamation, "ishakkutlu.com"
        GoTo Son
    End If
Next i
Say = ThisWorkbook.Worksheets(3).Range("B" & Rows.Count).End(xlUp).Row
For i = Say To 18 Step -1
    If IsDate(ThisWorkbook.Worksheets(3).Range("B" & i).Value) = False Then
        MsgBox "Y2 şubesinin dönem verilerinde, tarih formatına uymayan en az bir veri tespit edildi. Lütfen ilgili veriyi düzeltip tekrar deneyiniz.", vbOKOnly + vbExclamation, "ishakkutlu.com"
        GoTo Son
    End If
Next i
For i = Say To 18 Step -1
    If IsDate(ThisWorkbook.Worksheets(3).Range("J" & i).Value) = False Then
        MsgBox "Y2 şubesinin dönem verilerinde, tarih formatına uymayan en az bir veri tespit edildi. Lütfen ilgili veriyi düzeltip tekrar deneyiniz.", vbOKOnly + vbExclamation, "ishakkutlu.com"
        GoTo Son
    End If
Next i
Say = ThisWorkbook.Worksheets(4).Range("B" & Rows.Count).End(xlUp).Row
For i = Say To 18 Step -1
    If IsDate(ThisWorkbook.Worksheets(4).Range("B" & i).Value) = False Then
        MsgBox "Y'nin siparişlerine ilişkin dönem verilerinde, tarih formatına uymayan en az bir veri tespit edildi. Lütfen ilgili veriyi düzeltip tekrar deneyiniz.", vbOKOnly + vbExclamation, "ishakkutlu.com"
        GoTo Son
    End If
Next i
Say = ThisWorkbook.Worksheets(5).Range("B" & Rows.Count).End(xlUp).Row
For i = Say To 18 Step -1
    If IsDate(ThisWorkbook.Worksheets(5).Range("B" & i).Value) = False Then
        MsgBox "Y'nin acenta ücretine ilişkin dönem verilerinde, tarih formatına uymayan en az bir veri tespit edildi. Lütfen ilgili veriyi düzeltip tekrar deneyiniz.", vbOKOnly + vbExclamation, "ishakkutlu.com"
        GoTo Son
    End If
Next i

'Kontroller
If BaslangicTarihi.Value = "" Then
    MsgBox "Lütfen başlangıç tarihi seçiniz.", vbOKOnly + vbExclamation, "ishakkutlu.com"
    GoTo Son
End If
If BitisTarihi.Value = "" Then
    MsgBox "Lütfen bitiş tarihi seçiniz.", vbOKOnly + vbExclamation, "ishakkutlu.com"
    GoTo Son
End If
If CDate(BaslangicTarihi.Value) > CDate(BitisTarihi.Value) Then
    MsgBox "Raporlamada kullanılacak serilerin başlangıç tarihi, bitiş tarihinden sonraki bir tarih olamaz.", vbOKOnly + vbExclamation, "ishakkutlu.com"
    GoTo Son
End If

'MsgBox DateDiff("m", CDate(BaslangicTarihi.Value), CDate(BitisTarihi.Value)) + 1
DonemAraligi = DateDiff("m", CDate(BaslangicTarihi.Value), CDate(BitisTarihi.Value)) + 1
If DonemAraligi > 13 Then
    MsgBox "Raporlamada kullanılacak serilerin dönem aralığı " & DonemAraligi & " ay olarak seçildi. Ancak modülün varsayılan kurgusunda raporlama dönemine esas veriler maksimum 13 aylık olabilir." & vbNewLine & _
    "Raporlama işlemine 13 aylık seriler esas alınarak devam etmek için " & """" & "Evet/Yes" & """" & ", işlemi iptal etmek için " & """" & "Hayır/No" & """" & " butonunu tıklayınız.", vbYesNo + vbExclamation, "ishakkutlu.com"
    If Bilgi = vbYes Then
        GoTo RaporlamayaDevam
    ElseIf Bilgi = vbNo Then
        GoTo Son
    End If
End If
RaporlamayaDevam:

GlobalIlkTarih = Format(CDate(BaslangicTarihi.Value), "mmmm yyyy")
GlobalSonTarih = Format(CDate(BitisTarihi.Value), "mmmm yyyy")
'MsgBox GlobalIlkTarih
'MsgBox GlobalSonTarih


Set WsXFirma = ThisWorkbook.Worksheets(1)

Set IlkSatirBul = WsXFirma.Range("B:B").Find(What:=GlobalIlkTarih, SearchDirection:=xlNext, _
            SearchOrder:=xlByRows, LookIn:=xlValues, LookAt:=xlWhole)
If Not IlkSatirBul Is Nothing Then
    GlobalIlkSatir = IlkSatirBul.Row
End If

Set SonSatirBul = WsXFirma.Range("B:B").Find(What:=GlobalSonTarih, SearchDirection:=xlPrevious, _
            SearchOrder:=xlByRows, LookIn:=xlValues, LookAt:=xlWhole)
If Not SonSatirBul Is Nothing Then
    GlobalSonSatir = SonSatirBul.Row
End If

'MsgBox GlobalIlkSatir
'MsgBox GlobalSonSatir

'13 aya sabitle
If GlobalSonSatir - GlobalIlkSatir > 13 Then
    GlobalSonSatir = GlobalIlkSatir + 12
End If

Call ModuleReporting.Raporla

Unload Me

Son:
ThisWorkbook.Protect "123"

End Sub

Private Sub Kapat_Click()
    Unload Me
End Sub

Private Sub UserForm_Initialize()
Dim ClrLab As MSForms.Control

For Each ClrLab In RaporlamaArayuzu.Controls
    If TypeName(ClrLab) = "Label" Then
        ClrLab.BackColor = &H8000000F
        ClrLab.ForeColor = &H80000012
    End If
    If TypeName(ClrLab) = "CheckBox" Then
        ClrLab.BackColor = &H8000000F
        ClrLab.ForeColor = &H80000012
    End If
    If TypeName(ClrLab) = "OptionButton" Then
        ClrLab.BackColor = &H8000000F
        ClrLab.ForeColor = &H80000012
    End If
    If TypeName(ClrLab) = "Frame" Then
        ClrLab.BackColor = RGB(205, 205, 205)
        ClrLab.ForeColor = RGB(0, 0, 0)
        ClrLab.BorderColor = RGB(26, 168, 212)
    End If
Next ClrLab

UstMenuFrame.BackColor = RGB(205, 205, 205)
AltMenuFrame.BackColor = RGB(205, 205, 205)
LblBilgilendirme.BackColor = RGB(205, 205, 205)

Raporla.BackColor = RGB(205, 205, 205)
Raporla.ForeColor = &H80000012
Kapat.BackColor = RGB(205, 205, 205)
Kapat.ForeColor = &H80000012
RaporlamaArayuzu.BackColor = RGB(186, 200, 220)


Call FormuDuzenle


End Sub

Sub FormuDuzenle()
Dim Say As Long, i As Long

'On Error Resume Next
BaslangicTarihi.Clear
Say = ThisWorkbook.Worksheets(1).Range("B" & Rows.Count).End(xlUp).Row
If Say < 18 Then
    GoTo TarihBos
End If
'Combo değerleri
For i = Say To 18 Step -1
    If ThisWorkbook.Worksheets(1).Range("B" & i).Value <> "" Then
        With BaslangicTarihi
            .AddItem (Format(ThisWorkbook.Worksheets(1).Range("B" & i).Value, "mmmm yyyy"))
        End With
        With BitisTarihi
            .AddItem (Format(ThisWorkbook.Worksheets(1).Range("B" & i).Value, "mmmm yyyy"))
        End With
    End If
Next i
TarihBos:

End Sub

Formun algoritmalarının en başında ColorChangerGenel() adında bir prosedür göreceksiniz. Aşağıda yer alan çeşitli kontrollerin-nesnelerin Move prosedürleri ile senkronize çalışan ColorChangerGenel() prosedürü, bir nesnenin varsayılan arka plan ve yazı tipi rengini geri yükler. Örneğin fareyi “Raporla” butonunun üzerine getirirseniz, Raporla yazısı beyaz, arka planı ise açık mavi olacaktır (Tabiki design modda, yani editörde değil, ribbondan “Raporlama Arayüzü”ne tıkladığınızda bunu gözlemleyebilirsiniz). Bunu yapan Raporla_MouseMove prosedürüdür. Siz fareyi Raporla butonunun üzerine getirdiğinizde Raporla_MouseMove prosedürü çalışacak, fareyi başka bir nesnenin üzerine getirdiğinizde, örneğin Raporla butonunun konumlandırıldığı AltMenuFrame üzerine getirdiğinizde, AltMenuFrame_MouseMove prosedürünün içinde de yer alan ColorChangerGenel() prosedürü çalışarak Raporla butonunun arka plan ve yazı tipi rengini varsayılan renklere, yani arka planı gri, yazı tipini ise siyah renge döndürecektir.

Bir başka konu da açılır listeleri fare tekerleği ile kaydırmak. Daha önce (yukarıda) bu konuya değineceğimden bahsetmiştim. Örneğin BaslangicTarihi_MouseMove prosedüründe “Call SetComboBoxHook(BaslangicTarihi)” şeklinde bir satır göreceksiniz. SetComboBoxHook prosedürü, “ModuleScrollCombo” isimli modülün içinde yer alan fonksiyon tipi bir prosedürdür. Eğer BaslangicTarihi isimli açılır liste ögelerini genişlettiğimizde, fare işaretçisi bu ögelerin üzerinde herhangi bir yerde olmak koşuluyla, “ModuleScrollCombo” modülü içindeki SetComboBoxHook prosedürü BaslangicTarihi açılır listesi için çalışmaya başlayacaktır. Böylece BaslangicTarihi isimli açılır listeyi genişlettiğinizde, farenin tekerliğini hareket ettirmeniz sonucunda listeler aşağı veya yukarı doğru hareket edecektir. BaslangicTarihi_LostFocus prosedürü içine de “ModuleScrollCombo” modülü içinde yer alan RemoveComboBoxHook prosedürünü konumlandırmayı unutmayın! Aksi durumda kodların çalışması sırasında hata alabilirsiniz.

BaslangicTarihi_Change prosedürü içinde yer alan birkaç satırlık kod, ilgili açılır listeye, açılır listenin değerleri dışında başka bir değerin girilmesinin engellenmesini sağlar.

Bu arayüzün en önemli prosedürü “Raporla” (caption) butonunun (yine aynı isimde oluşturduğum ki aynı isimde olmak zorunda değildir) “Raporla” (name) isimli prosedürüdür. Bu prosedürün başında verilerin formatları kontrol edilir. Çünkü örneğin numerik olması gereken bir veri string gelirse prosedür hata verecektir. Tabi başlangıç ve bitiş tarihlerinde herhangi bir seçimin yapılıp yapılmadığı gibi standart kontroller de bulunur.

13 aydan daha uzun bir tarih aralığı girilmesi durumunda, kullanıcı bilgilendirilir ve kullanıcı devam etmek isterse, girilen dönem aralığı 13 aya indirgenerek işleme devam edilir. Burada daha önce değinilen GlobalIlkSatir ve GlobalSonSatir isimli iki global değişkeni göreceksiniz. Raporlama arayüzüne girilen başlangıç ve bitiş tarihleri, derleyici tarafından ilgili sayfada aranır ve satır numaraları bahsi geçen global değişkenlere aktarılır. Sonrasında ise işin büyük kısmını “ModuleReporting” isimli modülde yer alan “Raporla” isimli prosedürün gerçekleştirdiğini artık biliyoruz. Nitekim “RaporlamaArayuzu”nde yer alan “Raporla” prosedürünün sonunda bulunan Call ModuleReporting.Raporla satırı ile “Raporla” prosedürü işini, artık “ModuleReporting” isimli modülde yer alan “Raporla” isimli prosedüre devretmektedir.

Not: Raporla isimlerinin benzer olması aklınızı karıştırmasın; tamamen tesadüfi olarak isimleri aynı olmuş. “Raporla” isimli prosedür, biri “RaporlamaArayuzu”nde, diğeri ise “ModuleReporting” modülünde yer alan iki farklı prosedürdür.

UserForm_Initialize() isimli prosedür ise “Raporlama Arayüzü” açılırken renk vb. bazı biçimsel düzenlemeleri ve açılır listelerde yer alması gereken değerlerin açılır listelere atanması işini gerçekleştirmektedir.

3.6. Yardim

Bu formun çok fazla fonksiyonel özelliği bulunmamaktadır. Daha çok bilgilendirme amaçlı statik bir görevi yerine getirir. Algortimalara ulaşmak için Yardim objesi üzerine gelip sağ tık yaparak View Code sekmesini tıklayabilirsiniz. Kodların çalışma mantığının RaporlamaArayuzu ile çok benzer olduğunu göreceksiniz. Bu yüzden tekrar açıklama gereği duymuyorum. Ancak BilgilendirmeFrame_MouseMove prosedürü içinde yer alan HookListBoxScroll Me, Me.BilgilendirmeFrame satırından bahsetmeliyim. Bu satır “BilgilendirmeFrame” isimli frame’de yer alan dikey kaydırma çubuğunu fare tekerleği ile aşağı ve yukarı kaydırmaya olanak tanır. Bunu yapabilmek için elbette (daha önce bahsedilen) “ModuleScrollFrame” isimli modülde yer alan scriptlerden yararlanır. Diğer taraftan Yardim formu kapatıldğında, UserForm_QueryClose prosedürü içindeki tek satırlık UnhookListBoxScroll kodu, “ModuleScrollFrame” isimli modülde yer alan prosedür aracılığıyla frame’in kaydırma çubuğunu fare tekerleği ile hareket ettiren görevi sonlandırır. Bu sonlandırma işlemini yapmamanız durumunda, bilgisayarınız bir süre sonra zorlanmaya başlayabilir (bilgisayarı ve/veya Excel dosyasını kapatıp açtığınız söz konusu zorlanma gidecektir; kalıcı değildir, sadece proje dosyanız verimsiz çalışır) ve/veya debug/hata alabilirsiniz.

Option Explicit

Sub ColorChangerGenel()

If Kapat.BackColor <> RGB(205, 205, 205) Then
Kapat.BackColor = RGB(205, 205, 205)
Kapat.ForeColor = &H80000012
End If

End Sub

Private Sub Kapat_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
Kapat.BackColor = RGB(26, 168, 212)
Kapat.ForeColor = RGB(255, 255, 255)
End Sub

Private Sub UserForm_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
End Sub
Private Sub TasiyiciFrame_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
End Sub
Private Sub BaslikFrame_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
End Sub
Private Sub UstMenuFrame_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
End Sub


Private Sub BilgilendirmeFrame_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
HookListBoxScroll Me, Me.BilgilendirmeFrame
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
UnhookListBoxScroll
End Sub


Private Sub LblBilgilendirme_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
End Sub
Private Sub AltMenuFrame_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call ColorChangerGenel
End Sub

Private Sub Kapat_Click()
    Unload Me
End Sub

Private Sub UserForm_Initialize()
Dim ClrLab As MSForms.Control

For Each ClrLab In Yardim.Controls
    If TypeName(ClrLab) = "Label" Then
        ClrLab.BackColor = &H8000000F
        ClrLab.ForeColor = &H80000012
    End If
    If TypeName(ClrLab) = "CheckBox" Then
        ClrLab.BackColor = &H8000000F
        ClrLab.ForeColor = &H80000012
    End If
    If TypeName(ClrLab) = "OptionButton" Then
        ClrLab.BackColor = &H8000000F
        ClrLab.ForeColor = &H80000012
    End If
    If TypeName(ClrLab) = "Frame" Then
        ClrLab.BackColor = RGB(205, 205, 205)
        ClrLab.ForeColor = RGB(0, 0, 0)
        ClrLab.BorderColor = RGB(26, 168, 212)
    End If
Next ClrLab

UstMenuFrame.BackColor = RGB(205, 205, 205)
AltMenuFrame.BackColor = RGB(205, 205, 205)
LblBilgilendirme.BackColor = RGB(205, 205, 205)

Kapat.BackColor = RGB(205, 205, 205)
Kapat.ForeColor = &H80000012
Yardim.BackColor = RGB(186, 200, 220)

End Sub

4. Son Söz

Raporlama Modülünün çalışma ilkelerini ve algoritma mantığını, oldukça detaylı sayılabilecek şekilde anlatmaya çalıştım. Sorularınız varsa, yorumlara ya da info@ishakkutlu.com adresine yazarsanız mümkün olan en kısa sürede dönüş yapmaya çalışırım.  Faydalı olması dileğiyle.

 

 

İshak Kutlu, VBA Projeleri

Yorum Yap

İshak Kutlu

Veri & Otomasyon Uzmanı

Kurumsal iş akışlarını düzenleyen veri odaklı otomasyon sistemleri ve makine öğrenmesi tabanlı çözümler geliştirir. Gerçek operasyonel süreçler için ölçeklenebilir ve izlenebilir yapılar tasarlar.

YouTube   YouTube   YouTube   YouTube