VBA - Tür Uyuşmazlığı (Çalışma Zamanı Hatası 13)

Tür Uyuşmazlığı Hatası nedir?

VBA kodunuzu çalıştırdığınızda genellikle bir uyumsuzluk hatası oluşabilir. Hata, kodunuzun tamamen çalışmasını durduracak ve bu hatanın çözülmesi gereken bir mesaj kutusu aracılığıyla işaretlenecektir.

Kodunuzu kullanıcılara dağıtmadan önce tam olarak test etmediyseniz, bu hata mesajının kullanıcılar tarafından görüleceğini ve Excel uygulamanızda büyük bir güven kaybına neden olacağını unutmayın. Ne yazık ki, kullanıcılar genellikle bir uygulamaya çok tuhaf şeyler yaparlar ve genellikle geliştirici olarak sizin asla düşünmediğiniz şeylerdir.

Dim deyimini belirli bir tür olarak kullanarak bir değişken tanımladığınız için bir tür uyuşmazlığı hatası oluşur; tamsayı, tarih ve kodunuz değişkene kabul edilemez bir değer atamaya çalışıyor; bu örnekte olduğu gibi bir tamsayı değişkenine atanan metin dizesi:

İşte bir örnek:

Hata Ayıkla'ya tıklayın ve rahatsız edici kod satırı sarı renkle vurgulanacaktır. Hata açılır penceresinde devam etmek için bir seçenek yoktur, çünkü bu büyük bir hatadır ve kodun daha fazla çalıştırılmasına imkan yoktur.

Bu özel durumda çözüm, Dim ifadesini, değişkene atadığınız değerle çalışan bir değişken türüyle değiştirmektir. Değişken türünü 'String' olarak değiştirirseniz kod çalışır ve muhtemelen değişken adını da değiştirmek istersiniz.

Ancak, değişken türünü değiştirmek projenizin sıfırlanmasını gerektirecektir ve kodunuzu en baştan yeniden çalıştırmanız gerekecek, bu da uzun bir prosedür söz konusuysa çok can sıkıcı olabilir.

Çalışma Sayfası Hesaplamasından Kaynaklanan Uyumsuzluk Hatası

Yukarıdaki örnek, bir uyumsuzluk hatasının nasıl üretilebileceğinin çok basit bir örneğidir ve bu durumda kolayca giderilebilir.

Ancak, uyumsuzluk hatalarının nedeni genellikle bundan çok daha derindir ve kodunuzda hata ayıklamaya çalıştığınızda çok açık değildir.

Örnek olarak, bir çalışma sayfasında belirli bir konumda bir değer almak için kod yazdığınızı ve bu kodun, çalışma kitabındaki hesaplamaya bağlı diğer hücreleri içerdiğini varsayalım (bu örnekte B1)

Çalışma sayfası, bir metin dizesi içinde belirli bir karakteri bulmak için bir formül içeren bu örneğe benzer.

Kullanıcının bakış açısından, A1 hücresi serbest biçimdir ve istedikleri herhangi bir değeri girebilirler. Bununla birlikte, formül 'B' karakterinin bir oluşumunu arıyor ve bu durumda bulunamadı, dolayısıyla B1 hücresinde bir hata değeri var.

Aşağıdaki test kodu, A1 hücresine yanlış bir değer girildiğinden bir uyumsuzluk hatası üretecektir.

1234 Alt TestMismatch()MyNumber'ı Tamsayı Olarak KarartınMyNumber = Sayfalar("Sayfa1").Range("B1").ValueAlt Bitiş

Kullanıcı A1 hücresine beklenene uymayan ve 'B' karakterini içermeyen metin girdiği için B1 hücresindeki değer bir hata üretti.

Kod, bir tamsayı beklemek için tanımlanmış olan 'MyNumber' değişkenine değer atamaya çalışır ve böylece bir uyumsuzluk hatası alırsınız.

Bu, kodunuzu titizlikle kontrol etmenin cevabı sağlayamayacağı bu örneklerden biridir. Bunun neden olduğunu anlamak için değerin nereden geldiğine de bakmanız gerekir.

Sorun aslında çalışma sayfasındadır ve hata değerlerinin ele alınması için B1'deki formülün değiştirilmesi gerekir. Arama karakteri bulunamazsa, varsayılan 0 değerini sağlamak için 'EĞERHATA' formülünü kullanarak bunu yapabilirsiniz.

Ardından, sıfır değeri olup olmadığını kontrol etmek ve kullanıcıya A1 hücresindeki değerin geçersiz olduğuna dair bir uyarı mesajı görüntülemek için kodu dahil edebilirsiniz.

12345678 Alt TestMismatch()MyNumber'ı Tamsayı Olarak KarartınMyNumber = Sayfalar("Sayfa1").Range("B1").TextMyNumber = 0 iseMsgBox "A1 hücresindeki değer geçersiz", vbCriticalAlt ÇıkışBitirAlt Bitiş

Kullanıcının her istediğini yapmasını ve ilk etapta çalışma sayfası hatalarına neden olmasını durdurmak için elektronik tablodaki veri doğrulamasını (şeridin Veri sekmesindeki Veri Araçları grubu) da kullanabilirsiniz. Yalnızca çalışma sayfası hatalarına neden olmayacak değerler girmelerine izin verin.

Ne girildiğini kontrol etmek için çalışma sayfasındaki Change olayına göre VBA kodu yazabilirsiniz.

Ayrıca çalışma sayfasını kilitleyin ve parola ile koruyun, böylece geçersiz veriler girilemez

Girilen Hücre Değerlerinin Neden Olduğu Uyumsuzluk Hatası

Bir çalışma sayfasından (hata olmayan) normal değerler getirerek, ancak kullanıcının beklenmeyen bir değer girdiği durumlarda, kodunuzdaki uyumsuzluk hatalarına neden olabilir. bir sayı beklerken bir metin değeri. Bir hücreye sayı hakkında bir şeyler açıklayan bir not koyabilmek için bir sayı aralığı içine bir satır eklemeye karar vermiş olabilirler. Ne de olsa, kullanıcının kodunuzun nasıl çalıştığı hakkında hiçbir fikri yok ve notlarını girerek her şeyi çöplükten attılar.

Aşağıdaki örnek kod, tamsayı değerleriyle tanımlanan 'MyNumber' adlı basit bir dizi oluşturur.

Kod daha sonra A1'den A7'ye kadar olan bir hücre aralığı boyunca yinelenir ve her bir değeri indekslemek için bir 'Coun' değişkeni kullanarak hücre değerlerini diziye atar.

Kod metin değerine ulaştığında, bundan kaynaklanan bir uyumsuzluk hatası oluşur ve her şey durma noktasına gelir.

Açılan hata penceresinde 'Hata Ayıkla'yı tıkladığınızda, sorunun sarı renkle vurgulandığı kod satırını göreceksiniz. İmlecinizi kod içindeki 'Coun' değişkeninin herhangi bir örneğinin üzerine getirerek, kodun başarısız olduğu yerde 'Coun' değerini görebileceksiniz, bu durumda 5

Çalışma kağıdına baktığınızda, 5 olduğunu göreceksiniz.NS hücre aşağı metin değerine sahip ve bu, kodun başarısız olmasına neden oldu

Hücre değerini diziye eklemeden önce sayısal bir değeri kontrol eden bir koşul koyarak kodunuzu değiştirebilirsiniz.

12345678910111213 Alt TestMismatch()Dim MyNumber(10) Tamsayı Olarak, Tam Sayı Olarak SaySayı = 1YapmakEğer Sayı = 11 ise Çıkış YapIf Numeric(Sheets("sheet1").Cells(Coun, 1).Value) SonraMyNumber(Coun) = Sheets("sheet1").Cells(Coun, 1).ValueBaşkaNumaram(Sayı) = 0BitirSayı = Sayı + 1DöngüAlt Bitiş

Kod, değerin gerçekten bir sayı olup olmadığını test etmek için 'IsNumeric' işlevini kullanır ve eğer öyleyse diziye girer. Sayı değilse sıfır değerini girer.

Bu, dizi dizininin elektronik tablodaki hücre satır numaralarıyla aynı hizada tutulmasını sağlar.

Ayrıca, orijinal hata değerini ve konum ayrıntılarını bir "Hatalar" çalışma sayfasına kopyalayan bir kod da ekleyebilirsiniz, böylece kullanıcı, kodunuz çalıştırıldığında neyi yanlış yaptığını görebilir.

Sayısal test, değeri diziye atamak için kodun yanı sıra hücre için tam kodu kullanır. Aynı kodu tekrar etmemek için bunun bir değişkene atanması gerektiğini iddia edebilirsiniz, ancak sorun şu ki, değişkeni bir 'Varyant' olarak tanımlamanız gerekecek ki bu yapılacak en iyi şey değil.

Ayrıca, çalışma sayfasında veri doğrulamaya ve çalışma sayfasını parola ile korumaya ihtiyacınız vardır. Bu, kullanıcının satır eklemesini ve beklenmeyen veriler girmesini önleyecektir.

Parametreleri Kullanarak Bir Fonksiyonu veya Alt Rutini Çağırmanın Neden Olduğu Uyumsuzluk Hatası

Bir işlev çağrıldığında, genellikle işlev tarafından önceden tanımlanmış veri türlerini kullanarak işleve parametreler iletirsiniz. İşlev, VBA'da önceden tanımlanmış bir işlev olabilir veya kendi oluşturduğunuz Kullanıcı Tanımlı bir işlev olabilir. Bir alt rutin de bazen parametreler gerektirebilir

Parametrelerin fonksiyona nasıl aktarıldığına ilişkin kurallara bağlı kalmazsanız, bir uyumsuzluk hatası alırsınız.

12345678 Alt ÇağrıFonksiyonu()Tamsayı Olarak Ret DimRet = MyFunction(3, "test")Alt Bitişİşlev MyFunction(Tamsayı Olarak N, Dize Olarak T) Dizi Olarakİşlevim = TBitiş İşlevi

Uyumsuzluk hatası almak için burada birkaç olasılık var

Dönüş değişkeni (Ret) bir tamsayı olarak tanımlanır, ancak işlev bir dize döndürür. Kodu çalıştırır çalıştırmaz, işlev bir dize döndürdüğü için başarısız olur ve bu bir tamsayı değişkenine giremez. İlginç bir şekilde, bu kodda Hata Ayıklama çalıştırmak bu hatayı almaz.

İletilen ilk parametrenin (3) etrafına tırnak işaretleri koyarsanız, bu, işlevdeki (tamsayı) ilk parametrenin tanımıyla eşleşmeyen bir dize olarak yorumlanır.

İşlev çağrısındaki ikinci parametreyi sayısal bir değere dönüştürürseniz, dizedeki ikinci parametre bir dize (metin) olarak tanımlandığından bir uyumsuzlukla başarısız olur.

VBA'da Dönüştürme İşlevlerinin Yanlış Kullanılmasından Kaynaklanan Uyumsuzluk Hatası

Değerleri çeşitli veri türlerine dönüştürmek için VBA'da kullanabileceğiniz bir dizi dönüştürme işlevi vardır. Bir sayı içeren bir dizeyi bir tamsayı değerine dönüştüren 'CInt' buna bir örnektir.

Dönüştürülecek dize herhangi bir alfa karakteri içeriyorsa, dizenin ilk kısmı sayısal karakterler içerse ve geri kalanı alfa karakterlerinden oluşsa bile bir uyumsuzluk hatası alırsınız; '123abc'

Uyumsuzluk Hatalarının Genel Önlenmesi

Yukarıdaki örneklerde, kodunuzdaki olası uyumsuzluk hatalarıyla başa çıkmanın birkaç yolunu gördük, ancak en iyi seçenek olmasalar da birkaç başka yol daha var:

Değişkenlerinizi Varyant Türü olarak tanımlayın

Varyant türü, VBA'daki varsayılan değişken türüdür. Bir değişken için Dim ifadesi kullanmazsanız ve kodunuzda kullanmaya başlarsanız, otomatik olarak Variant tipi verilir.

Varyant değişkeni, tamsayı, uzun tamsayı, çift duyarlıklı sayı, boolean veya metin değeri olsun, her tür veriyi kabul eder. Bu kulağa harika bir fikir gibi geliyor ve neden herkesin tüm değişkenlerini değişken olarak ayarlamadığını merak ediyorsunuz.

Ancak, varyant veri türünün birkaç dezavantajı vardır. İlk olarak, diğer veri türlerinden çok daha fazla bellek kaplar. Çok büyük bir diziyi değişken olarak tanımlarsanız, VBA kodu çalışırken çok büyük miktarda bellek yutar ve kolayca performans sorunlarına neden olabilir.

İkincisi, belirli veri türlerini kullanmanıza göre genel olarak performansta daha yavaştır. Örneğin, kayan ondalık basamaklı sayıları kullanarak karmaşık hesaplamalar yapıyorsanız, sayıları çift duyarlıklı sayılar yerine değişkenler olarak saklarsanız hesaplamalar önemli ölçüde daha yavaş olacaktır.

Mutlak bir zorunluluk olmadıkça, varyant türünü kullanmak özensiz programlama olarak kabul edilir.

Hataları işlemek için OnError Komutunu kullanın

Hata yakalamayla başa çıkmak için OnError komutu kodunuza eklenebilir, böylece bir hata oluşursa kullanıcı standart VBA hata açılır penceresi yerine anlamlı bir mesaj görür.

1234567 Alt ErrorTrap()MyNumber'ı Tamsayı Olarak KarartınHatada Err_Handler'a GitMyNumber = "deneme"Err_Handler:MsgBox "Hata " & Err.Description & " oluştu"Alt Bitiş

Bu, hatanın kodunuzun düzgün çalışmasını durdurmasını etkili bir şekilde önler ve kullanıcının hata durumundan temiz bir şekilde kurtulmasını sağlar.

Err_Handler rutini, hata ve bu konuda kiminle iletişime geçileceği hakkında daha fazla bilgi gösterebilir.

Programlama açısından, bir hata işleme rutini kullandığınızda, hatanın bulunduğu kod satırını bulmak oldukça zordur. F8'i kullanarak kodda adım adım ilerliyorsanız, sorunlu kod satırı çalıştırılır çalıştırılmaz, hata işleme rutinine atlar ve nerede yanlış gittiğini kontrol edemezsiniz.

Bunu aşmanın bir yolu, True veya False (Boolean) olan global bir sabit ayarlamak ve bunu bir 'If' deyimi kullanarak hata işleme rutinini açmak veya kapatmak için kullanmaktır. Hatayı test etmek istediğinizde tek yapmanız gereken global sabiti False olarak ayarlamaktır ve hata işleyici artık çalışmayacaktır.

1 Global Const ErrHandling = Yanlış
1234567 Alt ErrorTrap()MyNumber'ı Tamsayı Olarak KarartınErrHandling = True ise Hatada Err_Handler'a GitMyNumber = "deneme"Err_Handler:MsgBox "Hata " & Err.Description & " oluştu"Alt Bitiş

Bununla ilgili bir sorun, kullanıcının hatadan kurtulmasına izin vermesidir, ancak alt yordam içindeki kodun geri kalanı, daha sonra uygulamada çok büyük yankı uyandırabilecek şekilde çalıştırılmaz.

Bir dizi hücre arasında döngü oluşturmaya ilişkin önceki örneği kullanarak, kod A5 hücresine ulaşır ve eşleşmeyen hatayı verir. Kullanıcı, hata hakkında bilgi veren bir mesaj kutusu görür, ancak o hücreden itibaren aralıktaki hiçbir şey işlenmez.

Hataları Bastırmak için OnError Komutunu kullanın

Bu, 'Hata Devam Ediyor Sonraki' komutunu kullanır. Bu, sonraki hataların gösterilmesini engellediği için kodunuza dahil edilmesi çok tehlikelidir. Bu, temel olarak, kodunuz yürütülürken, bir kod satırında bir hata meydana gelirse, yürütmenin, hata satırını yürütmeden bir sonraki kullanılabilir satıra geçeceği ve normal şekilde devam edeceği anlamına gelir.

Bu, olası bir hata durumunu çözebilir, ancak yine de koddaki gelecekteki her hatayı etkileyecektir. Daha sonra kodunuzun hatasız olduğunu düşünebilirsiniz, ancak aslında öyle değildir ve kodunuzun bazı kısımları, yapması gerektiğini düşündüğünüz şeyi yapmıyor.

Bu komutun kullanılmasının gerekli olduğu durumlar vardır, örneğin 'Kill' komutunu kullanarak bir dosyayı siliyorsanız (dosya yoksa, bir hata olacaktır), ancak hata yakalama her zaman geri alınmalıdır. aşağıdakiler kullanılarak olası hatanın meydana gelebileceği yerin hemen ardından açık:

1 Hatada 0 Git

Bir hücre aralığı arasında döngü oluşturmaya ilişkin önceki örnekte, 'Sonraki Hatada Devam Et' kullanılarak bu, döngünün devam etmesini sağlar, ancak hataya neden olan hücre diziye aktarılmaz ve söz konusu dizin için dizi öğesi boş bir değer tutacaktır.

Verileri Beyannameyle Eşleşecek Bir Veri Türüne Dönüştürme

Gelen verilerin veri türünü, alıcı değişkenin veri türüyle eşleşecek şekilde değiştirmek için VBA işlevlerini kullanabilirsiniz.

Bunu, parametrelere işlevlere aktarırken yapabilirsiniz. Örneğin, bir dize değişkeninde tutulan bir numaranız varsa ve bunu bir işleve sayı olarak iletmek istiyorsanız, CInt kullanabilirsiniz.

Kullanılabilecek birkaç dönüştürme işlevi vardır, ancak başlıcaları şunlardır:

CInt - sayısal değeri olan (+ veya - 32.768'in altında) bir dizeyi bir tamsayı değerine dönüştürür. Bunun herhangi bir ondalık noktayı kestiğini unutmayın.

CLng - Sayısal değeri büyük olan bir dizeyi uzun bir tam sayıya dönüştürür. Ondalık noktalar kesilir.

CDbl - Kayan bir ondalık sayıyı tutan bir dizeyi çift duyarlıklı sayıya dönüştürür. Ondalık noktaları içerir

CDate - Tarih içeren bir dizeyi tarih değişkenine dönüştürür. Kısmen, Windows Denetim Masası'ndaki ayarlara ve tarihin nasıl yorumlandığına ilişkin yerel ayarınıza bağlıdır.

CStr - Sayısal veya tarih değerini bir dizeye dönüştürür

Bir dizeden bir sayıya veya tarihe dönüştürülürken, dize, sayılar veya tarih dışında hiçbir şey içermemelidir. Alfa karakterleri varsa, bu bir uyumsuzluk hatası üretecektir. Uyumsuzluk hatası üretecek bir örnek:

123 Alt Test()MsgBox CInt("123abc")Alt Bitiş

Kodunuzdaki Değişkenleri Test Etme

Bir değişkeni, belirli bir türdeki bir değişkene atamadan önce, hangi veri türü olduğunu öğrenmek için test edebilirsiniz.

Örneğin, VBA'da 'IsNumeric' işlevini kullanarak bir dizenin sayısal olup olmadığını kontrol edebilirsiniz.

1 MsgBox IsNumeric("123test")

Bu kod False döndürür, çünkü dize sayısal karakterlerle başlasa da metin de içerdiğinden testi geçemez.

1 MsgBox IsNumeric("123")

Bu kod, tümü sayısal karakterlerden oluştuğu için True değerini döndürür.

VBA'da çeşitli veri türlerini test etmek için bir dizi işlev vardır, ancak bunlar başlıca şunlardır:

IsNumeric - bir ifadenin sayı olup olmadığını test eder

IsDate - bir ifadenin tarih olup olmadığını test eder

IsNull - bir ifadenin boş olup olmadığını test eder. Boş bir değer yalnızca bir değişken nesneye yerleştirilebilir, aksi takdirde 'Geçersiz Null Kullanımı' hatası alırsınız. Bir soru sormak için kullanıyorsanız, bir mesaj kutusu boş bir değer döndürür, bu nedenle dönüş değişkeninin bir değişken olması gerekir. Boş bir değer kullanan herhangi bir hesaplamanın her zaman boş sonucunu döndüreceğini unutmayın.

IsArray - ifadenin bir diziyi temsil edip etmediğini test eder

IsEmpty - ifadenin boş olup olmadığını test eder. Boşun boş ile aynı olmadığını unutmayın. Bir değişken ilk tanımlandığında boştur ancak boş bir değer değildir.

Şaşırtıcı bir şekilde, IsText veya IsString için gerçekten yararlı olabilecek bir işlev yoktur.

Nesneler ve Uyumsuzluk Hataları

Aralık veya sayfa gibi nesneler kullanıyorsanız, çalışma zamanında değil, derleme zamanında bir uyumsuzluk hatası alırsınız, bu da size kodunuzun çalışmayacağına dair gerekli uyarıyı verir.

123456 Alt TestRange()Menzil Olarak Dim MyRange, Ben Kadar UzunMyRange = Aralık ("A1:A2") olarak ayarlayınben = 10x = UseMyRange(I)Alt Bitiş
12 İşlev UseMyRange(R As Range)Bitiş İşlevi

Bu kodun "UseMyRange" adlı bir işlevi ve bir aralık nesnesi olarak iletilen bir parametresi vardır. Ancak, iletilen parametre, veri türüyle eşleşmeyen bir Uzun Tam Sayıdır.

VBA kodunu çalıştırdığınızda hemen derlenir ve şu hata mesajını görürsünüz:

Sorunlu parametre mavi bir arka planla vurgulanacaktır

Genel olarak, nesneleri kullanarak VBA kodunda hata yaparsanız, tür uyuşmazlığı mesajı yerine bu hata mesajını görürsünüz:

Arkadaşlarınızla sayfasını paylaşan sitenin gelişimine yardımcı olacak

wave wave wave wave wave