Genel Bakış
CopyFromRecordset (Range.CopyFromRecordset method), bir ADO ya da DAO Recordset nesnesindeki kayıtları, belirttiğiniz hücreden başlayarak çalışma sayfasına kopyalayan Range yöntemidir. Veritabanı sorgusunun sonucunu döngü kurmadan, hücre hücre yazmaya gerek kalmadan sayfaya aktardığı için hem kısa hem hızlıdır.
Recordset'te OLE nesnesi ya da ikili (binary) alan varsa aktarım hata verebilir; sorgunuzda yalnızca gerekli alanları seçin. Kayıt sayısı sayfanın satır sınırını aşarsa da hata alırsınız.
Makro çalıştığında A2:C4 aralığına Defter, Kalem ve Dosya kayıtları adet ve fiyat bilgileriyle yazılır; başlık satırına dokunulmaz. Kod ADO nesnesi oluşturduğu için bu sayfada çalıştırılmaz, sonucu kendi Excel'inizde deneyebilirsiniz. MoveFirst satırını silerseniz imleç son kayıtta kaldığı için yalnızca son kayıt aktarılır.
Kod bir veritabanı dosyasına bağlandığı için bu sayfada çalıştırılmaz. Kendi dosyanızda çalıştırdığınızda sorgunun döndürdüğü kayıtlar tutara göre büyükten küçüğe A2 hücresinden itibaren listelenir, Tutar sütunu sayı biçimi alır ve sütun genişlikleri ayarlanır. Bağlantı ve Recordset, hata olsa bile Temizle etiketinde kapatılır. ACE sağlayıcısı bilgisayarınızda kurulu değilse bağlantı satırında hata alırsınız.
Birinci çağrı yalnızca üç kaydı A2:C4 aralığına yazar. İkinci çağrı, imleç dördüncü kayıtta beklediği için kalan iki kaydı A5:C6 aralığına ekler; sonuçta tüm kayıtlar tek liste olarak görünür. Başlık döngüsü sütun adlarını Recordset'ten aldığı için sorgu değiştiğinde başlıkları elle düzeltmeniz gerekmez. E1 hücresine yazılan değer True olur; çünkü kopyalama tamamlandığında EOF özelliği True olur. Bu kod da ADO nesnesi oluşturduğundan sayfada çalıştırılmaz.
Söz dizimi
Yöntem, hedef aralığın sol üst hücresinden başlayarak kayıtları satır satır, alanları da sütun sütun yazar:
VBA
5 satır
ifade.CopyFromRecordset(Data, MaxRows, MaxColumns)
' Örnek kullanım
ActiveSheet.Range("A2").CopyFromRecordset rs
ActiveSheet.Range("A2").CopyFromRecordset rs, 100, 3
- ifade: Range nesnesi. Aktarım bu aralığın yalnızca sol üst hücresinden başlar; aralığın boyutu sonucu etkilemez.
- Data: Zorunlu. Açık bir ADO ya da DAO Recordset nesnesi.
- MaxRows: İsteğe bağlı. Aktarılacak en fazla kayıt sayısı. Verilmezse Recordset'teki tüm kalan kayıtlar kopyalanır.
- MaxColumns: İsteğe bağlı. Aktarılacak en fazla alan (sütun) sayısı. Verilmezse tüm alanlar kopyalanır.
Nasıl çalışır
Kopyalama, Recordset'in geçerli kaydından başlar. Yani imleç ilk kayıtta değilse önceki kayıtlar aktarılmaz. Kopyalama bitince imleç son kaydın ardına geçer ve EOF özelliği True olur. Aynı Recordset'i ikinci kez kopyalamak isterseniz önce MoveFirst yöntemini çağırmalısınız.- Alan adları: Yalnızca kayıt verileri aktarılır, sütun başlıkları aktarılmaz. Başlıkları Fields(i).Name özelliğiyle kendiniz yazın.
- Biçimler: Tarih, para birimi gibi değerler sayfaya ham değer olarak gelir. Gerekirse NumberFormat özelliğiyle hücre biçimini ayrıca ayarlayın.
- Sınırlı aktarım: MaxRows ile sayfalayarak aktarım yapabilirsiniz; imleç kaldığı yerde durduğundan ikinci çağrı kalan kayıtlarla devam eder.
- Üzerine yazma: Hedefteki dolu hücreler uyarı verilmeden ezilir. Eski sonuçları önce ClearContents ile temizleyin.
Ne zaman tercih edilir
Veritabanından ya da bellekteki bir Recordset'ten çok sayıda kayıt alıyorsanız hücre hücre yazan bir Do While Not rs.EOF döngüsü yerine bu yöntem çok daha hızlıdır. Bağlantıyı sayfada kalıcı tutmak ve sonradan yenilemek istiyorsanız Veri > Veri Al ve Dönüştür > Veri Al (Data > Get & Transform Data > Get Data) komutları ya da QueryTables koleksiyonu daha uygun olabilir.Recordset'te OLE nesnesi ya da ikili (binary) alan varsa aktarım hata verebilir; sorgunuzda yalnızca gerekli alanları seçin. Kayıt sayısı sayfanın satır sınırını aşarsa da hata alırsınız.
1. Bellekte kurulan Recordset'i sayfaya aktarma
Standart modüle aşağıdaki kodu yapıştırın. Makro, veritabanı gerektirmeden bellekte üç alanlı bir ADO Recordset kurar, kayıtları ekler ve A2 hücresinden başlayarak sayfaya döker. Sayfada yalnızca başlıklar vardır. Kayıt ekledikten sonra imleç son kayıtta kalacağından kopyalamadan önce MoveFirst çağrılır.
VBA
33 satır
Option Explicit
' Bellekte bir Recordset kurar ve A2 hücresinden başlayarak sayfaya aktarır
Sub BellekRecordsetAktar()
Dim rs As Object
Dim ws As Worksheet
Set ws = ActiveSheet
Set rs = CreateObject("ADODB.Recordset")
With rs
.CursorLocation = 3 ' 3 = adUseClient
.LockType = 3 ' 3 = adLockOptimistic
.Fields.Append "Ürün", 200, 40 ' 200 = adVarChar
.Fields.Append "Adet", 3 ' 3 = adInteger
.Fields.Append "Fiyat", 6 ' 6 = adCurrency
.Open
.AddNew Array("Ürün", "Adet", "Fiyat"), Array("Defter", 120, 18.5)
.AddNew Array("Ürün", "Adet", "Fiyat"), Array("Kalem", 340, 4.25)
.AddNew Array("Ürün", "Adet", "Fiyat"), Array("Dosya", 75, 12)
.Update
' İmleç son kayıtta olduğundan başa dönmek gerekir
.MoveFirst
End With
' Kayıtları A2'den başlayarak yaz
ws.Range("A2").CopyFromRecordset rs
rs.Close
Set rs = Nothing
End Sub
CopyFromRecordset
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | Ürün | Adet | Fiyat |
Ürün ListesiExcelDepo v1.0.0
2. Access veritabanından sorgu sonucu alma
Standart modüle yapıştırın ve veritabanı yolunu kendi dosyanıza göre değiştirin. Makro, Satis.accdb dosyasındaki Siparisler tablosundan tutarı 1000'in üzerindeki kayıtları çeker, eski sonuçları temizler ve A2 hücresinden başlayarak sayfaya yazar. Başlıklar sayfada hazırdır.
VBA
39 satır
Option Explicit
Sub VeritabanindanAktar()
Dim cn As Object
Dim rs As Object
Dim ws As Worksheet
On Error GoTo Hata
Set ws = ActiveSheet
Set cn = CreateObject("ADODB.Connection")
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Veri\Satis.accdb;"
' Sorgu sonucunu Recordset olarak al
Set rs = cn.Execute("SELECT Musteri, Sehir, Tutar FROM Siparisler WHERE Tutar > 1000 ORDER BY Tutar DESC")
' Eski sonuçları temizle, yenisini yaz
ws.Range("A2:C" & ws.Rows.Count).ClearContents
ws.Range("A2").CopyFromRecordset rs
' Tutar sütununa biçim ver
ws.Range("C2", ws.Cells(ws.Rows.Count, "C").End(xlUp)).NumberFormat = "#,##0.00"
ws.Columns("A:C").AutoFit
Temizle:
If Not rs Is Nothing Then
If rs.State = 1 Then rs.Close
End If
If Not cn Is Nothing Then
If cn.State = 1 Then cn.Close
End If
Set rs = Nothing
Set cn = Nothing
Exit Sub
Hata:
MsgBox "Aktarım yapılamadı: " & Err.Description, vbExclamation
Resume Temizle
End Sub
CopyFromRecordset
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | Müşteri | Şehir | Tutar |
Sipariş RaporuExcelDepo v1.0.0
3. MaxRows ile parça parça aktarma
Standart modüle yapıştırın. Makro bellekte beş kayıtlı bir Recordset kurar, başlıkları Fields koleksiyonundan yazar, önce MaxRows ile ilk üç kaydı A2 hücresine, ardından imleç kaldığı yerden devam ettiği için kalan kayıtları A5 hücresine aktarır.
VBA
43 satır
Option Explicit
Sub ParcaParcaAktar()
Dim rs As Object
Dim ws As Worksheet
Dim i As Long
Set ws = ActiveSheet
Set rs = CreateObject("ADODB.Recordset")
With rs
.CursorLocation = 3
.LockType = 3
.Fields.Append "Personel", 200, 40
.Fields.Append "Şehir", 200, 30
.Fields.Append "Satış", 6
.Open
.AddNew Array("Personel", "Şehir", "Satış"), Array("Ayşe Demir", "Ankara", 12500)
.AddNew Array("Personel", "Şehir", "Satış"), Array("Mehmet Kaya", "İzmir", 9800)
.AddNew Array("Personel", "Şehir", "Satış"), Array("Elif Şahin", "Bursa", 15200)
.AddNew Array("Personel", "Şehir", "Satış"), Array("Can Yıldız", "Adana", 7600)
.AddNew Array("Personel", "Şehir", "Satış"), Array("Zeynep Arslan", "Konya", 11100)
.Update
.MoveFirst
End With
' Başlıkları alan adlarından yaz
For i = 0 To rs.Fields.Count - 1
ws.Cells(1, i + 1).Value = rs.Fields(i).Name
Next i
' İlk üç kaydı A2'ye yaz; imleç 4. kayıtta kalır
ws.Range("A2").CopyFromRecordset rs, 3
' Kalan kayıtlar A5'ten devam eder
ws.Range("A5").CopyFromRecordset rs
' Kopyalama bittiğinde EOF True olur
ws.Range("E1").Value = rs.EOF
rs.Close
Set rs = Nothing
End Sub
CopyFromRecordset
Formülünü incelemek için bir hücre seçin.| A | B | C | |
|---|---|---|---|
| 1 | Personel | Şehir | Satış |
Satış ÖzetiExcelDepo v1.0.0
Kullanırken dikkat edin
- Kayıt imleci başta olmalı: Kopyalama geçerli kayıttan başlar. AddNew sonrası ya da daha önce bir kopyalama yapıldıysa imleç sonda kalır; yöntemi çağırmadan önce MoveFirst kullanın, aksi halde eksik ya da boş sonuç alırsınız.
- Başlıklar kopyalanmaz: Alan adlarını sayfaya kendiniz yazın; Fields koleksiyonunda bir döngüyle Fields(i).Name değerini ilk satıra aktarmak en güvenli yoldur.
- Hedef alan ezilir: Yöntem hedefteki dolu hücreleri uyarı vermeden değiştirir. Her çalıştırmada önce eski veriyi ClearContents ile temizleyin ve tablo ya da biçimlendirilmiş aralığın boyutunu kontrol edin.
- Sınırlar ve hatalar: Kayıt sayısı sayfanın satır sınırını aşarsa, Recordset kapalıysa ya da OLE/ikili alan içeriyorsa hata oluşur. Sorguda yalnızca gereken alanları seçin. Korumalı sayfada hedef hücreler kilitliyse de hata alırsınız.
- Başvuru ekleme gerekmez: Kodda CreateObject ile geç bağlama kullanırsanız Visual Basic Düzenleyicisi'nde ADO başvurusu eklemeniz gerekmez. Erken bağlama için Araçlar > Başvurular (Tools > References) altında Microsoft ActiveX Data Objects kitaplığını işaretleyebilirsiniz. Veri türü sabitleri (adVarChar gibi) geç bağlamada tanınmayabileceğinden örneklerde sayısal değerleri kullandık.
- İlgili konular:
- Range.CurrentRegion: Aktarılan verinin kapsadığı bölgeyi seçmek için
- Range.ClearContents: Eski sonuçları temizlemek için
- Range.NumberFormat: Tarih ve tutar biçimini ayarlamak için
- Range.AutoFit: Sütun genişliklerini ayarlamak için
- QueryTables.Add: Yenilenebilir sorgu tablosu oluşturmak için
- Recordset.GetRows: Kayıtları diziye almak için
- Veri > Veri Al ve Dönüştür > Veri Al (Data > Get & Transform Data > Get Data): Kod yazmadan dış veri bağlamak için