Özellik ikonu

Redim

İndirme izni yok

Genel Bakış

ReDim (Redimension), VBA'da dinamik bir dizinin eleman sayısını ve sınırlarını program çalışırken yeniden belirleyen deyimdir. Kaç veri geleceği önceden bilinmediğinde, örneğin bir sütundaki dolu hücreleri toplarken diziyi gerektiği kadar büyütmeye yarar. Preserve anahtar sözcüğüyle birlikte kullanılırsa dizideki mevcut değerler korunur.

Söz dizimi​

ReDim deyimi, daha önce parantezi boş bırakılarak bildirilmiş dinamik bir diziye (ya da Variant türündeki bir değişkene) boyut kazandırır. Aynı deyimde virgülle ayırarak birden çok dizi yeniden boyutlandırılabilir.
VBA 7 satır
ReDim [Preserve] degisken(altSinir To ustSinir, ...) [As tur]

' Ornek: tek boyutlu ve iki boyutlu dizi
Dim liste() As String
Dim tablo() As Double
ReDim liste(1 To 10)
ReDim tablo(1 To 5, 1 To 3)
  • Preserve: İsteğe bağlıdır; varsayılan olarak yoktur ve yoksa dizideki tüm değerler silinir. Yazılırsa eski değerler korunur.
  • degisken: Yeniden boyutlandırılacak dizinin adıdır. Dizi dinamik olmalıdır (Dim ad() biçiminde bildirilmiş) ya da Variant türünde bir değişken olmalıdır.
  • altSinir: İsteğe bağlıdır; yazılmazsa varsayılan 0'dır (Option Base 1 kullanılıyorsa 1).
  • ustSinir: Zorunludur; boyuttaki en büyük dizin numarasıdır. Değişken ya da hesaplanmış bir değer olabilir.
  • As tur: İsteğe bağlıdır. Yazılırsa Dim deyimindeki veri türüyle aynı olmalıdır; türü ReDim ile değiştirmek yalnızca Variant değişkenlerde mümkündür.

Başlangıç değerleri ve dinamik dizi hazırlığı​

ReDim, sabit boyutlu diziyi değiştiremez. Dim a(1 To 5) ile bildirilmiş bir diziye ReDim uygulanırsa Excel derleme hatası verir. Dinamik dizi için parantez boş bırakılır ve boyut sonradan ReDim ile verilir.
Preserve kullanılmadan ReDim çalıştığında dizi sıfırlanır. Sayısal diziler 0, String dizileri boş metin, Variant dizileri Empty, Object dizileri Nothing değerini alır.
Dizinin sınırlarını öğrenmek için LBound ve UBound işlevleri kullanılır. Dizinin içeriğini silip belleği geri vermek için Erase deyimi uygundur.

Preserve kullanımı ve sınırları​

ReDim Preserve ile dizi büyütülür ya da küçültülür, eski değerler korunur. Küçültülürse sığmayan elemanlar kaybolur. Preserve için şu kurallar geçerlidir:
  • Yalnız son boyut: Çok boyutlu dizilerde yalnızca son boyutun üst sınırı değiştirilebilir. Örneğin (1 To 3, 1 To 2) dizisinde yalnızca ikinci boyut büyütülebilir.
  • Boyut sayısı: Boyut sayısı değiştirilemez; tek boyutlu dizi iki boyutlu yapılamaz.
  • Alt sınır: Preserve ile alt sınır değiştirilemez.
  • İlk kullanım: Henüz boyutlandırılmamış dinamik dizide de ReDim Preserve hata vermeden çalışır; bu sayede döngüde diziyi eleman eleman büyütmek kolaylaşır.
Her ReDim Preserve çağrısı diziyi bellekte yeniden oluşturup kopyaladığı için çok büyük döngülerde yavaşlatır; mümkünse önce yeterince büyük boyut verip sonunda küçültün.

1. Koşula uyan ürünleri diziye toplama​

A sütununda ürünler, B sütununda sipariş adetleri var. Kaç ürünün koşulu sağlayacağı bilinmediği için dizi her uygun üründe ReDim Preserve ile büyütülür; adedi 50 ve üzeri olan ürünler sonunda C sütununa yazılır. Kodu standart modüle yapıştırın.
VBA 26 satır
Option Explicit

Sub YuksekAdetListele()
    Dim ws As Worksheet
    Dim secilen() As String   ' dinamik dizi
    Dim sayac As Long, i As Long, sonSatir As Long

    Set ws = ActiveSheet
    sonSatir = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    For i = 2 To sonSatir
        If ws.Cells(i, 2).Value >= 50 Then
            sayac = sayac + 1
            ' Eski elemanlari koruyarak diziyi bir eleman buyut
            ReDim Preserve secilen(1 To sayac)
            secilen(sayac) = ws.Cells(i, 1).Value
        End If
    Next i

    ' Hic urun secilmediyse dizi boyutlanmamistir
    If sayac = 0 Then Exit Sub

    For i = 1 To sayac
        ws.Cells(i + 1, 3).Value = secilen(i)
    Next i
End Sub
Redim
Formülünü incelemek için bir hücre seçin.
ABC
1ÜrünAdetSeçilen Ürün
2Defter80Defter
3Kalem35Silgi
4Silgi120Dosya
5Dosya60Kağıt
6Zımba20Bant
7Kağıt200
8Makas45
9Bant90
SiparişlerExcelDepo v1.0.0
Makro, adedi 50 ve üzeri olan ürünleri sırayla C sütununa yazar. İlk seçilen ürün Defter, ikincisi Silgi hücresindedir; listenin devamı Dosya, Kağıt ve Bant hücrelerinde yer alır. Dizi her uygun üründe bir eleman büyüdüğü için boyutu baştan bilmeniz gerekmez.

2. İki boyutlu dizide son boyutu büyütme​

Tabloda üç şehrin Ocak, Şubat ve Mart satışları var. Makro önce iki aylık veriyi (1 To 3, 1 To 2) boyutlu bir diziye alır, sonra ReDim Preserve ile ikinci boyutu 3'e çıkarıp Mart verisini ekler ve her şehrin toplamını E sütununa yazar. Kodu standart modüle yapıştırın.
VBA 33 satır
Option Explicit

Sub AyEkleVeTopla()
    Dim ws As Worksheet
    Dim veri() As Double
    Dim i As Long, j As Long
    Dim toplam As Double

    Set ws = ActiveSheet

    ' Once Ocak ve Subat (2 sutun)
    ReDim veri(1 To 3, 1 To 2)
    For i = 1 To 3
        For j = 1 To 2
            veri(i, j) = ws.Cells(i + 1, j + 1).Value
        Next j
    Next i

    ' Yalnizca SON boyut buyutulur; eski veriler korunur
    ReDim Preserve veri(1 To 3, 1 To 3)
    For i = 1 To 3
        veri(i, 3) = ws.Cells(i + 1, 4).Value
    Next i

    ' Her sehrin toplamini yaz
    For i = 1 To 3
        toplam = 0
        For j = 1 To 3
            toplam = toplam + veri(i, j)
        Next j
        ws.Cells(i + 1, 5).Value = toplam
    Next i
End Sub
Redim
Formülünü incelemek için bir hücre seçin.
ABCDE
1ŞehirOcakŞubatMartToplam
2Ankara120135150405
3İzmir200180210590
4Bursa9011095295
Şehir SatışExcelDepo v1.0.0
Üç aylık toplamlar E sütununa yazılır: Ankara için 405, İzmir için 590, Bursa için 295. Dizinin ikinci boyutu ReDim Preserve ile 2'den 3'e çıktığı için Ocak ve Şubat verileri kaybolmadan Mart sütunu eklenebilmiştir. İlk boyutu (şehir sayısını) Preserve ile değiştirmeye çalışsaydınız çalışma zamanı hatası alırdınız.

3. Preserve ile Preserve olmadan farkı​

Makro 5 elemanlı bir Long dizisi oluşturup ilk elemana 10 değerini verir. Sonra diziyi önce ReDim Preserve ile, ardından Preserve olmadan büyütür ve her adımda üst sınırı ile ilk elemanı sayfaya yazar. Kodu standart modüle yapıştırın.
VBA 25 satır
Option Explicit

Sub PreserveFarki()
    Dim a() As Long
    Dim ws As Worksheet

    Set ws = ActiveSheet

    ' 1. adim: ilk dizi
    ReDim a(1 To 5)
    a(1) = 10
    a(2) = 20
    ws.Cells(2, 2).Value = UBound(a)
    ws.Cells(2, 3).Value = a(1)

    ' 2. adim: Preserve ile buyutme - degerler korunur
    ReDim Preserve a(1 To 8)
    ws.Cells(3, 2).Value = UBound(a)
    ws.Cells(3, 3).Value = a(1)

    ' 3. adim: Preserve olmadan buyutme - degerler sifirlanir
    ReDim a(1 To 12)
    ws.Cells(4, 2).Value = UBound(a)
    ws.Cells(4, 3).Value = a(1)
End Sub
Redim
Formülünü incelemek için bir hücre seçin.
ABC
1AdımÜst Sınırİlk Eleman
2İlk dizi510
3Preserve ile büyütme810
4Preserve olmadan büyütme120
Dizi TestiExcelDepo v1.0.0
İlk adımda üst sınır 5, ilk eleman 10 olarak yazılır. Preserve ile büyütmeden sonra üst sınır 8 olur ve ilk eleman 10 değerini korur. Preserve olmadan yapılan son ReDim'de üst sınır 12 olur, fakat ilk eleman 0 değerine sıfırlanır; çünkü Preserve yazılmayan ReDim diziyi baştan oluşturur.

Kullanırken dikkat edin​

  • Preserve unutulursa veri kaybolur: Döngüde diziyi büyütürken Preserve sözcüğünü yazmayı unutmak en sık yapılan hatadır. Kod hata vermez, ama her seferinde dizi sıfırlanır ve yalnızca son eleman dolu kalır.
  • Sabit boyutlu diziye ReDim uygulanmaz: Dim a(1 To 5) gibi boyutu bildirimde verilmiş bir dizi sabittir; ReDim uygulanırsa derleme hatası oluşur. Boyutu sonradan değiştirmek istiyorsanız diziyi Dim a() biçiminde bildirin.
  • Çok boyutlu dizilerde yalnız son boyut: ReDim Preserve ile yalnızca son boyutun üst sınırı değişebilir. Satır sayısı sonradan artacaksa veriyi (sütun, satır) düzeninde tutup satırı son boyut yapmak ya da diziyi baştan boyutlandırıp kopyalamak gerekir.
  • Veri türü ve performans: ReDim ile Dim'deki veri türü değiştirilemez; yalnız Variant değişkenlerde farklı tür atanabilir. Her ReDim Preserve dizinin kopyalanmasına yol açtığı için on binlerce elemanlık döngülerde diziyi önce büyük açıp sonunda küçültmek ya da bir seferde Range.Value ile dizi almak daha hızlıdır.
  • Dizinin boyutlanıp boyutlanmadığını denetleme: Hiç ReDim uygulanmamış dinamik dizide UBound çağrılırsa 'Subscript out of range' hatası alırsınız. Bu yüzden eleman eklemeden önce bir sayaç tutmak ya da hata denetimi yapmak iyi bir uygulamadır.
  • İlgili konular: Dim deyimi, Erase deyimi, Static deyimi, Option Base, UBound ve LBound işlevleri, Array ve Split işlevleri, Range.Value ile dizi okuma, For...Next döngüsü.
Örneklerdeki makroların tamamı indirilebilir Excel dosyasındadır (.xlsm). Dosyayı açtıktan sonra makroları etkinleştirin, ardından Alt + F11 ile Visual Basic Düzenleyicisi'nde kodları inceleyebilir ve Alt + F8 ile çalıştırabilirsiniz.
Yazar
ExcelDepo
İndirme sayısı
0
Gösterim
12
İlk yayın
Güncel

Puanlar

0.00 Oylama 0 İnceleme
Geri
Üst