OĞUZ EROL · MarkdownEN
Markdown’ı açKapat
Kaynak: https://oguzerol.com/google-sheets-query-rapor-uygulamasi/

[![Örnek senaryo: metin olarak girilmiş bir tarih QUERY raporundan 1011 numaralı siparişi düşürür; kontrol hücresi satırı gösterir, tarih düzeltilince Ege 8 siparişle birinci sıraya çıkar.](https://oguzerol.com/gorseller/hizmet-kapaklari/google-sheets-query-rapor-uygulamasi-webapp-v1-tr.webp)

Görseli büyüt](https://oguzerol.com/gorseller/hizmet-kapaklari/google-sheets-query-rapor-uygulamasi-webapp-v1-tr.webp)

# Google Sheets QUERY ile Filtreli Rapor Hazırlama

[Oğuz Erol](https://oguzerol.com/hakkimda/)  |  15 dk okuma

Google E-Tablolar’da filtreli rapor için QUERY işlevi şöyle yazılır: `=QUERY(veri; "sorgu"; 1)`. Sorgu metni `select`, `where`, `group by`, `pivot`, `order by`, `label` ve `format` yan cümlelerinden oluşur, son bağımsız değişken başlık satırı sayısıdır. Türkiye yerel ayarlı dosyada bağımsız değişkenler noktalı virgülle ayrılır. Filtreli rapor için ayrı bir sekmeye, bölgenin seçildiği bir açılır liste ve iki tarih hücresi koyarsınız. QUERY bu hücreleri `&` ile sorgu metnine ekler. En büyük tuzak, QUERY’nin hata vermeden eksik sonuç döndürebilmesidir: tarih sütununda metin olarak girilmiş tek bir tarih, o siparişi rapordan sessizce düşürür.

Sınır da baştan belli: aynı dosyayı herkes görür, kişiye göre satır gizlenemez, rapor kaynağın bir kopyasıdır.

## QUERY nasıl yazılır ve Türkçe ayarda ne değişir?

QUERY üç bağımsız değişken alır: sorgulanacak aralık, tırnak içindeki sorgu metni ve aralığın başındaki başlık satırı sayısı. Google’ın [Türkçe yardım sayfası](https://support.google.com/docs/answer/3093343?hl=tr) sözdizimini `QUERY(veriler; sorgu; [başlıklar])` diye veriyor. Başlık sayısı yazılmazsa Google, verinin içeriğine bakarak tahmin eder. Ben her zaman `1` yazıyorum, tahmine bırakmıyorum.

Sorgu metni Google’ın sorgu dilindedir. [Sorgu dili başvurusuna](https://developers.google.com/chart/interactive/docs/querylanguage) göre yan cümleler bu sırayla yazılmak zorunda:

1. `select`: hangi sütunlar (`select A, C, F`)
2. `where`: hangi satırlar (`where C = 'Ege'`)
3. `group by`: gruplama (`group by C`, yanında `sum(F)`, `count(A)` gibi toplama)
4. `pivot`: bir sütunun değerlerini yeni sütunlara açma
5. `order by`: sıralama (`order by sum(F) desc`)
6. `limit`, `offset`: kaç satır, kaçıncıdan başlayarak
7. `label`: sonuç başlığını değiştirme
8. `format`: sonuç biçimi

Aynı başvuruya göre anahtar kelimelerde büyük/küçük harf fark etmez, ama sütun adları ve tırnak içindeki metinler harfe duyarlıdır. `'İptal'` ile `'iptal'` iki ayrı değerdir: `where G = 'iptal'` testte hata vermedi, hiç satır da bulmadı.

**Türkçe yerel ayar.** Yerel ayar Dosya > Ayarlar’da (File > Settings) durur. Türkiye ayarlı bir test dosyasında virgüllü formül “Formula parse error” hatası verdi, aynı formül noktalı virgülle çalıştı. ABD ayarlı dosya ise noktalı virgülü kabul edip kendiliğinden virgüle çevirdi. Sorgu metninin içindeki virgüller (`select A, B`) her iki ayarda da virgül kalır, çünkü tırnak içindeki metin formül değil, sorgudur. İnternetten bulduğunuz bir İngilizce örneği yapıştırırken yalnız tırnak dışındaki virgülleri değiştirin.

**İşlev adı.** Bu sayfadaki formüller İngilizce işlev adlarıyla (TEXT, IF, ISTEXT) yazıldı. Google’ın [yerel ayar sayfasına](https://support.google.com/docs/answer/58515?hl=en) göre işlev adlarının dili ayrı bir ayardır (“Always use English function names”). Türkçe arayüzde formülünüz tanınmazsa önce bu ayara bakın.

## Örnek: dağıtım firmasında bölge ve dönem raporu

Firma, müşteri kodları ve rakamlar kurgusaldır.

Endüstriyel rulman, kayış ve zincir dağıtan bir firmanın dört bölge satış ekibi var: Marmara, Ege, Akdeniz ve İç Anadolu. Siparişler tek bir Google E-Tablolar dosyasında, `Siparisler` sekmesinde tutuluyor. Sütunlar: A Sipariş No, B Tarih, C Bölge, D Müşteri, E Ürün, F Tutar (KDV hariç TL), G Durum (Açık, Sevk edildi, İptal). Sekmede 28 sipariş var, tarihleri 01.07.2026 ile 07.08.2026 arasında.

Satış müdürü her bölge sorumlusuna aynı soruyu soruyor: 01.07.2026–31.07.2026 döneminde, iptaller hariç, kaç sipariş ve ne kadar tutar? Dört satır şöyle görünüyor:

| No | Tarih | Bölge | Tutar | Durum |
| --- | --- | --- | --- | --- |
| 1009 | 13.07.2026 | İç Anadolu | 40.150 | Sevk edildi |
| 1010 | 14.07.2026 | Ege | 7.350 | İptal |
| 1011 | `15.07.2026` (metin) | Ege | 41.200 | Sevk edildi |
| 1012 | 16.07.2026 | Akdeniz | 11.200 | Sevk edildi |

1011’in tarihi başka bir dosyadan düz metin olarak yapıştırılmış. Ekranda diğer tarihlerden farkı yok gibi, ama E-Tablolar onu tarih değil metin olarak tutuyor.

Ege sorumlusu raporda bölgeyi Ege seçiyor. QUERY **7 sipariş, 115.300 TL** gösteriyor. Gerçekte dönemde iptal edilmemiş **8 sipariş, 156.500 TL** var. Aradaki fark tek bir satır: 1011, 41.200 TL. Rapor hata vermiyor, uyarı göstermiyor.

Fark bir karara dokunuyor. Bölge özetinde QUERY Marmara’yı 154.250 TL ile birinci, Ege’yi 115.300 TL ile ikinci gösteriyor. 1011 düzeltilince Ege 156.500 TL ile birinci oluyor. Bölge primini ya da stok önceliğini bu tabloya bakarak belirleyen bir müdür, yanlış bölgeyi öne alır.

Bu örneği 16 Ekim 2026’da Türkiye yerel ayarlı gerçek bir Google E-Tablolar dosyasında kurdum. Formülleri Sheets API ile girdim, sonuçları okudum. Aynı veriyi QUERY mantığını taklit eden bir Python betiğiyle de hesapladım. Sayfadaki her rakam iki yolda da aynı çıktı.

## Rapor sekmesi adım adım nasıl kurulur?

Rapor sekmesi seçim hücrelerinden ve onları okuyan QUERY formüllerinden oluşur. Kaynak sekmeye kimse dokunmaz, rapor sekmesine kimse veri yazmaz. Örnekteki yerleşim:

- `Rapor!B1` Bölge (açılır liste), `B2` Başlangıç tarihi, `B3` Bitiş tarihi, `B4` Müşteri (kesme işareti örneği için)
- `A6` filtreli sipariş listesi, `H6` bölge özeti, `H13` bölge × ürün tablosu
- `D1` ve `F1` kontrol hücreleri

### 1. Açılır liste ve tarih hücreleri

Ayrı bir `Ayarlar` sekmesinde A2:A6’ya dört bölgeyi ve “Tümü” seçeneğini yazın. B1’i seçip Insert > Dropdown ya da Data > Data validation yolundan “Dropdown (from a range)” ölçütüyle bu aralığı gösterin ([Google Yardım](https://support.google.com/docs/answer/186103?hl=en), 16 Ekim 2026). Menü adlarını Google’ın İngilizce yardımından veriyorum, Türkçe arayüzde karşılıkları farklı görünebilir. Google’a göre listede olmayan bir değer varsayılan olarak reddedilir. “Egee” yazımı rapora hiç ulaşmaz.

B2 ve B3’e tarihleri gerçek tarih olarak girin (Türkiye ayarında `01.07.2026`). Hücrenin sağa yaslanması tarih olarak tanındığını gösterir.

### 2. Filtreli liste: hücreden ölçüt almak

`Rapor!A6`:

```
=QUERY(Siparisler!A1:G;"select A, B, E, F, G where G <> 'İptal' and B >= date '"&TEXT(B2;"yyyy-mm-dd")&"' and B <= date '"&TEXT(B3;"yyyy-mm-dd")&"' and C = '"&B1&"' order by B";1)
```

Formül sorgu metnini parçalardan kurar. `'"&B1&"'` parçasında dıştaki tek tırnak sorgu dilinin metin tırnağıdır, çift tırnak formülün metin tırnağıdır, `&` aradaki hücre değerini ekler. B1’de Ege varsa sorgunun sonu `and C = 'Ege' order by B` olur.

Tarih ölçütü daha katıdır. Sorgu dili tarihi yalnız `date 'yyyy-MM-dd'` biçiminde kabul eder. `TEXT(B2;"yyyy-mm-dd")` hücredeki tarihi bu biçime çevirir. Türkiye ayarlı test dosyasında `2026-07-01` üretti, biçim kodu Türkçe ayarda da İngilizce harflerle yazılıyor.

Sonuç (B1 = Ege):

| No | Tarih | Ürün | Tutar | Durum |
| --- | --- | --- | --- | --- |
| 1002 | 02.07.2026 | Kayış | 12.650 | Sevk edildi |
| 1005 | 07.07.2026 | Rulman | 27.300 | Sevk edildi |
| 1007 | 09.07.2026 | Zincir | 9.800 | Sevk edildi |
| 1014 | 20.07.2026 | Zincir | 14.900 | Sevk edildi |
| 1017 | 23.07.2026 | Rulman | 21.450 | Açık |
| 1020 | 28.07.2026 | Kayış | 10.900 | Açık |
| 1023 | 31.07.2026 | Rulman | 18.300 | Açık |

1010 iptal olduğu için listede yok, bu doğru. 1011’in yokluğu ise hata.

### 3. Bölge özeti: GROUP BY, ORDER BY, LABEL, FORMAT

Özet ve pivot tablo bilerek bütün bölgeleri gösterir, B1’e bakmaz. `Rapor!H6`:

```
=QUERY(Siparisler!A1:G;"select C, count(A), sum(F) where B >= date '"&TEXT(B2;"yyyy-mm-dd")&"' and B <= date '"&TEXT(B3;"yyyy-mm-dd")&"' and G <> 'İptal' group by C order by sum(F) desc label C 'Bölge', count(A) 'Sipariş', sum(F) 'Tutar' format sum(F) '#,##0'";1)
```

| Bölge | Sipariş | Tutar |
| --- | --- | --- |
| Marmara | 5 | 154.250 |
| Ege | 7 | 115.300 |
| İç Anadolu | 4 | 88.950 |
| Akdeniz | 3 | 69.800 |

`label` olmadan başlıklar “count Sipariş No” ve “sum Tutar” diye gelir. `format sum(F) '#,##0'` biçim kodunda virgül binlik ayırıcıyı temsil eder. Türkiye ayarlı dosyada sonuç `154.250` diye, noktayla göründü. Toplam 19 sipariş, 428.300 TL. Düzeltilmiş veride 20 sipariş, 469.500 TL olmalıydı.

### 4. Bölge × ürün: PIVOT

`Rapor!H13`:

```
=QUERY(Siparisler!A1:G;"select C, sum(F) where B >= date '"&TEXT(B2;"yyyy-mm-dd")&"' and B <= date '"&TEXT(B3;"yyyy-mm-dd")&"' and G <> 'İptal' group by C pivot E";1)
```

| Bölge | Kayış | Rulman | Zincir |
| --- | --- | --- | --- |
| Akdeniz | 11.200 | 58.600 | (boş) |
| Ege | 23.550 | 67.050 | 24.700 |
| Marmara | 28.650 | 101.000 | 24.600 |
| İç Anadolu | 8.600 | 40.150 | 40.200 |

Sorgu dili başvurusuna göre `pivot` toplama gerektirir, bu yüzden `sum(F)` ve `group by C` birlikte yazılır. Ürün sütunları alfabetik sırayla açıldı. Akdeniz’in tek zincir siparişi (1016) iptal olduğu için o hücre sıfır değil boş geldi. Bu tabloyu başka bir formülle toplayacaksanız boş hücreyi hesaba katın. Ege’nin rulman toplamı da 1011 yüzünden 67.050 TL görünüyor, düzeltilince 108.250 TL.

### 5. “Tümü” seçeneği

Bölüm 2’deki liste formülü “Tümü” seçilince boş döner, çünkü hiçbir satırın bölgesi “Tümü” değildir. Düzeltmek için formülün içindeki şu parçayı:

```
and C = '"&B1&"'
```

bununla değiştirin:

```
"&IF(B1="Tümü";"";" and C = '"&B1&"'")&"
```

B1’de “Tümü” varsa bölge koşulu sorgudan tamamen çıkar, başka bir değer varsa eklenir. Değiştirilmiş formülü test dosyasında iki kolda da çalıştırdım: “Tümü” seçiliyken dört bölgeden 19 sipariş geldi, Ege seçiliyken yukarıdaki 7 satır.

### 6. Kontrol hücreleri: sessiz hatayı görünür yapmak

QUERY hatalı veriyi atlarken uyarmaz, bu yüzden raporun yanına iki kontrol koyarım. `Rapor!D1` tarih sütununda metin olarak duran hücreleri sayar, `Rapor!F1` bunların sipariş numaralarını listeler:

```
=SUMPRODUCT(--ISTEXT(Siparisler!B2:B))
=IFERROR(FILTER(Siparisler!A2:A;ISTEXT(Siparisler!B2:B));"Yok")
```

Örnekte D1 1 döndürdü, F1 bu IFERROR’lu hâliyle 1011’i gösterdi. D1 sıfır değilse rapor eksik demektir. “Yok” kolunu denemedim, çünkü test verisinde metin tarih hep vardı. Aynı kontrolü tutar sütunu için `ISTEXT(Siparisler!F2:F)` ile kurun.

**Metin tarihi düzeltmek.** Tek hücreyi yeniden tarih olarak girebilirsiniz. Türkiye ayarlı dosyada hem `DATEVALUE("15.07.2026")` hem `DATEVALUE(Siparisler!B12)` doğru tarihi verdi. Yüzlerce satırı toplu düzeltmek için boş bir sütuna şu formülü yazın, sonucu kopyalayıp B sütununa değer olarak yapıştırın:

```
=ARRAYFORMULA(IF(Siparisler!B2:B29="";"";IF(ISTEXT(Siparisler!B2:B29);DATEVALUE(Siparisler!B2:B29);Siparisler!B2:B29)))
```

Testte 28 satırın hepsi tarih seri numarasına döndü, 1011 doğru günü aldı. Aralığı kendi son satırınıza göre değiştirin. Hücreleri tarih biçimine çevirmeyi unutmayın.

**Ölçüt hücresi metin olursa?** Başlangıç tarihini ayrı bir test hücresine `01.07.2026` diye düz metin olarak yazdım. TEXT yine `2026-07-01` üretti ve sorgu doğru çalıştı, çünkü E-Tablolar tanıdığı bir tarih metnini çevirdi. Tanınmayan bir metni (ör. “1 Tem”) denemedim. Açılır listeye benzer şekilde B2 ve B3’e tarih doğrulaması koymak bu riski azaltır.

**Kayıt yoksa ne olur?** Filtreye uyan satır yoksa QUERY hata vermez, yalnız başlık satırını döndürür. Testte `IFERROR` bunu yakalamadı, çünkü ortada hata yok. “Kayıt yok” mesajı için sonucun satır sayısına bakın:

```
=IF(ROWS(QUERY(Siparisler!A1:G;"select A where C = 'Karadeniz'";1))<2;"Kayıt yok";QUERY(Siparisler!A1:G;"select A where C = 'Karadeniz'";1))
```

Veride olmayan bir bölgeyle “Kayıt yok” yazdı, Ege ile listeyi getirdi. Formül sorguyu iki kez yazar; kendi uzun sorgunuzda ikisini birlikte değiştirin.

**Binlerce satırda?** Bu sayfadaki ölçümler 28 siparişle yapıldı. QUERY’nin on binlerce satırda ne kadar sürede hesapladığını ölçmedim.

## QUERY’de sık görülen hatalar ve nedenleri

QUERY hatalarının yarısı ekranda hata olarak görünür, diğer yarısı eksik ya da boş sonuç olarak. Sekiz durumun sekizini de test dosyasında ürettim: yedisini tabloda yazdığı gibi, #N/A satırını süslü parantezli bir diziyle. IMPORTRANGE ile deneyemedim:

| Belirti | Neden | Çözüm |
| --- | --- | --- |
| “Formula parse error” | Türkiye ayarlı dosyada bağımsız değişkenler virgülle ayrılmış | Tırnak dışındaki virgülleri noktalı virgül yapın |
| #VALUE!, “Invalid date literal” | Tarih `date '01.07.2026'` diye yazılmış | `date 'yyyy-MM-dd'`, hücreden alınıyorsa `TEXT(B2;"yyyy-mm-dd")` |
| Hata yok, sonuç boş | Tarih `date` sözcüğü olmadan metinle karşılaştırılmış (`B >= '2026-07-01'`) | Karşılaştırmaya `date` ekleyin |
| Hata yok, satır eksik | Sütunda karışık veri türü: metin tarih ya da metin tutar | Kontrol hücresi, kaynakta düzeltme |
| #N/A | Süslü parantezli dizide sütun harfi kullanılmış (IMPORTRANGE’de denenmedi) | `Col1`, `Col2` yazımı |
| #VALUE!, “PARSE_ERROR” | Hücreden gelen ölçütte kesme işareti var (`MK'101`) | Ölçütü sorguda çift tırnağa alın |
| Hata yok, sayım sıfır yerine boş | Metin harfi tutmuyor (`'iptal'`, veride `İptal`) | Değeri açılır listeden seçtirin |
| Sonuç sayfanın sonuna kadar uzuyor | Açık aralıkta boş satırlar da dönüyor | `where A is not null` ekleyin |

**Karışık veri türü.** Google’ın QUERY sayfası kuralı açıkça yazıyor: bir sütunda karışık veri türleri varsa çoğunluktaki tür sütunun türünü belirler, azınlıktaki türler null sayılır. Örnekte tarih sütununda 27 tarih ve 1 metin var. Metin null oldu, null bir değer tarih aralığına giremediği için 1011 düştü. `select A, B, F where A = 1011` sorgusu sipariş numarasını ve tutarı getirdi, tarih hücresini boş getirdi. Aynı şey tutar sütununda “41.200 TL” gibi metin olarak girilmiş bir tutarda da olur: satır listede görünür, toplama girmez.

**Kesme işareti ve tırnak.** Sorgu dili başvurusuna göre metin tek ya da çift tırnakla yazılabilir. Hücredeki değerde kesme işareti varsa (`MK'101`, `3/4'' hortum`, `Ali'nin Yeri`) tek tırnaklı sorgu metni o noktada kırılır. Testte “PARSE_ERROR” hatası verdi. Ölçütü sorgunun içinde çift tırnağa alın. Formülde bir çift tırnak, iki çift tırnakla yazılır. B4’teki müşteri ölçütüyle:

```
=QUERY(Siparisler!A1:G;"select A where D = """&B4&"""";1)
```

Bu yazım hatasız çalıştı. Ölçütün kendisinde çift tırnak varsa bu kez onu temizlemeniz gerekir. Değeri açılır listeden seçtirmek iki sorunu birden kapatır.

**Tarih ve saat.** Tarih sütununda saat de varsa sorgu dili `datetime 'yyyy-MM-dd HH:mm:ss'` biçimini kullanır. Örnekte saat yok, bu durumu denemedim.

**Boş satırlar.** `Siparisler!A1:G` gibi açık bir aralık, sayfadaki boş satırları da kapsar. Filtresiz `select A, C` sorgusu test dosyasında 1.000 satır döndürdü, yani sayfanın tamamını. `where A is not null` eklenince 29 satıra indi: başlık ve 28 sipariş. Tarih filtresi olan sorgularda boş satırlar zaten elenir, filtresiz listelerde bu koşulu ekleyin.

## Süslü parantezli dizi ve IMPORTRANGE ile QUERY: neden Col1?

QUERY’ye verilen veri süslü parantezli bir dizi olduğunda (`{Siparisler!A1:G}`) sütun harfleri çalışmadı, sırayla adlandırma çalıştı: `select C, sum(F)` #N/A verdi, `select Col3, sum(Col6) ... group by Col3` doğru toplamları getirdi. Google’ın QUERY sayfası yalnız iki yazımın da kabul edildiğini söylüyor. IMPORTRANGE sonucu da tek bir aralık değil, başka dosyadan gelen bir dizidir. Bu yüzden orada da `Col` yazımını kullanırım, ama IMPORTRANGE’li hâli API ile deneyemedim: dosyalar arası bağlantı izni arayüzden “Allow access” ile veriliyor. Bölge dosyasındaki formül şöyle olur:

```
=QUERY(IMPORTRANGE("kaynak-dosya-adresi";"Siparisler!A1:G");"select Col1, Col2, Col4, Col6 where Col3 = 'Ege'";1)
```

Google’ın [IMPORTRANGE sayfasına](https://support.google.com/docs/answer/3093340?hl=en) göre işlev, dosya açıkken saatte bir güncelleme kontrol eder (16 Ekim 2026). Dosya sayısı arttıkça hangi kaynağın ne zaman güncellendiğini izlemek ayrı bir iş olur. O durumu [merkezi veri paneli sayfasında](https://oguzerol.com/importrange-yerine-merkezi-veri-paneli/) anlattım.

## Google Sheets’te bu rapor nerede yetmez?

QUERY raporu, raporu okuyan herkes bütün siparişleri görebiliyorsa yeter. Ege sorumlusu yalnız Ege’yi görmeliyse, E-Tablolar’da bu ayrımı güvenle kuramazsınız. Üç sınır var:

**Herkes aynı dosyayı görür.** Paylaşım dosya düzeyindedir: dosyayı açabilen, `Siparisler` sekmesinin tamamını açabilir. Açılır listeden Ege seçmek bir görünümdür, yetki değildir. Google’ın [sayfa koruma yardımına](https://support.google.com/docs/answer/1218656?hl=en) göre gizlenen bir sayfa korunan sayfa sayılmaz ve görüntüleyenler gizli sayfadaki içeriğe yine erişebilir. Korunan aralıklar için Google şunu yazıyor: “This shouldn’t be used as a security measure.” Kişiler korunan bir dosyanın kopyasını alabilir, yazdırabilir, dışa aktarabilir.

**Bölge başına ayrı dosya da satırı gizlemez.** Akla gelen yol, her bölgeye kendi dosyasını açıp kaynaktan IMPORTRANGE ve QUERY ile yalnız o bölgeyi çekmek. Google’ın IMPORTRANGE sayfasına göre bağlantı izni bir kez verildiğinde hedef dosyadaki her düzenleyici, kaynak dosyanın herhangi bir yerinden veri çekebilir. Ege dosyasında düzenleme yetkisi olan biri, formülü değiştirip Marmara’nın siparişlerini de getirebilir. Bölge dosyasını yalnız görüntüleme yetkisiyle paylaşırsanız bu kez bölge sorumlusu dosyaya hiçbir şey giremez.

**Rapor kaynağın kopyasıdır.** QUERY veriyi okur, düzeltmez. 1011’in tarihini rapordan düzeltemezsiniz, kaynağa gidersiniz. Kaynağı kimin, ne zaman, neden değiştirdiği de raporda görünmez. Dört bölgenin ayrı dosyası olduğunda her biri kaynağın saatlik bir kopyasıdır, kaynaktaki hata dördüne birden geçer.

Bu sınırlar raporun kötü olduğunu göstermez. Kişiye göre veri ayrımı gerekmiyorsa yukarıdaki kurulum yeter ve bakımı kolaydır.

## Rol ve yetki tabanlı panel nerede başlar?

Rol ve yetki tabanlı panel, aynı raporu farklı kişilerin farklı satırlarla görmesi ve bu ayrımın atlanamaz olması gerektiğinde başlar. Karar için tablo:

| Durumunuz | Önerim | Neden |
| --- | --- | --- |
| Raporu okuyan herkes bütün bölgeleri görebilir, veriyi bir iki kişi giriyor | Sheets + QUERY | Gizlenecek satır yok, kontrol hücresi sessiz hatayı yakalar |
| Herkes her şeyi görebilir ama bölgeler kendi siparişini kendisi giriyor | Sheets, giriş için açılır liste ve veri doğrulama | Giriş hataları kaynağında azalır, yetki sorunu yok |
| Bölge sorumlusu yalnız kendi bölgesini görmeli ya da kimin neyi değiştirdiği izlenmeli | Rol ve yetki tabanlı panel | Satır ayrımı ve değişiklik izi Sheets’te güvenle kurulamıyor |

İlk iki satırdaysanız bu sayfadaki kurulum işinizi görür: örnekteki 41.200 TL’lik farkı kapatan şey bir panel değil, kontrol hücresidir.

Panelde yetki ekranda gizleme değil, sorgu kuralı olarak kurulabilir: Ege sorumlusunun isteği veritabanından yalnız Ege’nin satırlarını döndürecek biçimde. Aynı ilkeyi [kişiye atanan kayıtlar takip ekranında](https://oguzerol.com/kisiye-atanan-kayitlar-takip-ekrani/) ayrıntılı anlattım. Bu firmada satış müdürü bütün bölgeleri, bölge sorumlusu yalnız kendi bölgesini görür. Önerdiğim kural: kimse kendi girdiği siparişin iptalini onaylamaz. Tanımlanan iş kuralı veri girilirken uygulanır: tarih alanı metni reddedecek biçimde kurulabilir, böylece 1011 gibi bir satır panelde oluşmaz.

**Yapay zekâ.** Panelde her rakam tanımlı bir sorgudan gelir, yapay zekâ rakam üretmez. Model açıklama önerebilir, örneğin “Ege’de dönemin en büyük siparişi 41.200 TL”. Yetki filtresinden geçmemiş hiçbir satırın modele gitmemesi kurulabilir: Ege sorumlusunun gördüğü açıklama yalnız onun görebildiği satırlardan oluşur.

**Teslim.** Uygulama şirketiniz adına açılabilen bir sunucuda (VPS) çalışır. Veri sizindir, istediğiniz an Excel ya da CSV olarak alırsınız. Küçük ve orta ölçekli ekipte kullanıcı başına lisans yoktur, maliyet sunucu ve bakımdır. Kaynak kod erişiminizdeki bir depoda, çalıştırma talimatı, bağımlılık listesi ve bilinen sınırlarla durur. Kapsam ilk adımda yazılı belirlenir. Diğer örnekler [ekibiniz için özel web uygulamaları sayfasında](https://oguzerol.com/ekibiniz-icin-ozel-web-uygulamalari/).

**Sheets’teki veri ne olur?** Mevcut sipariş sekmesi panele aktarılır. Önerdiğim kural: metin tarihler ve metin tutarlar aktarımda ayrı bir listeye düşer, düzeltilmeden içeri alınmaz. 1011 de bu listede düzeltilip öyle girer. Rapor sekmeniz karşılaştırma için durur: panelin bölge özeti, aynı dönem için kontrol hücresi sıfır olan QUERY sonucuyla birebir tutmalıdır.

Rapor sekmenizin bir kopyasını [iletişim sayfasından](https://oguzerol.com/iletisim/) gönderin. İlk görüşmede hangi satırların rapordan sessizce düştüğüne ve kişiye göre ayrımın gerekip gerekmediğine birlikte bakarız.

## Sıkça Sorulan Sorular

### QUERY yerine FILTER kullanırsam bu tuzaktan kurtulur muyum?

Hayır. Aynı test dosyasında Ege ve tarih koşullarıyla FILTER’ı denedim: o da 1011’i düşürdü, 7 sipariş ve 115.300 TL döndürdü. FILTER tarih karşılaştırmasını `date` sözcüğü olmadan, doğrudan hücreyle yapar. Gruplama, sıralama ve başlık değiştirme gerekiyorsa QUERY daha kısadır. Hangisini seçerseniz seçin kontrol hücresi gerekir. Pivot tabloyu bu veride denemedim.

### QUERY sonucunun üzerine yazarsam ne olur?

Formülün tamamı bozulur. Testte liste alanındaki tek bir hücreye not yazınca formül #REF! verdi ve liste kayboldu: sonuç, veri olan hücrenin üzerine dökülmüyor. Sonuçta not tutmak istiyorsanız notu yan sütuna yazın ya da sonucu değer olarak başka bir sekmeye yapıştırıp kopyanın tarihini yanına not edin.

### QUERY formülünü yapay zekâya yazdırabilir miyim?

Yazdırabilirsiniz. Sütun harflerini, yerel ayarınızı ve hangi hücrelerden ölçüt alınacağını verirseniz taslak çoğu zaman doğru yapıda gelir. Ancak model verinizi görmeden formül yazar: tarih sütununda metin olarak duran bir hücreyi bilemez. Formülü kullanmadan önce kontrol hücresini kurun ve sonucu bir bölge için elle saydığınız toplamla karşılaştırın.

[Başa dön ↑](https://oguzerol.com/google-sheets-query-rapor-uygulamasi/#icerik)

## Bunları da okumak ister misiniz?

[Google Sheets IMPORTRANGE: Bağlantı ve Merkezi Veri PaneliGoogle Sheets IMPORTRANGE izinlerini, güncelleme gecikmesini ve kaynak zincirini değerlendirin. Gerektiğinde güncelliği görünen merkezi veri paneli kuruyorum.](https://oguzerol.com/importrange-yerine-merkezi-veri-paneli/)[Google Sheets Webden Veri Çekme: IMPORTHTML ile BaşlangıçGoogle Sheets webden veri çekme için IMPORTHTML örneğini deneyin. Tablo kaynağı, yenileme ve eski verinin görünürlüğünü kontrol ederek uygun yöntemi seçin.](https://oguzerol.com/google-sheets-webden-veri-cekme/)[Google Sheets E-posta Bildirimi ve Eşik UyarılarıGoogle Sheets e-posta bildirimi seçeneklerini değerlendirin. Gider veya stok eşiği için tekrar bildirim, sorumlu ve kapanma kuralları olan akış kuruyorum.](https://oguzerol.com/google-sheets-esik-uyari-uygulamasi/)

[Tüm yazılara göz atın →](https://oguzerol.com/yazilarim/)

NE İSTEYEBİLİRSİNİZ

## Nasıl çalışıyorum?
Çalışma saati paketleri

WhatsApp’tan ya da telefonda işinizden ve ihtiyacınızdan bahsedin; **5 ile 40 saat arasında bir çalışma paketinde** anlaşalım, ben gerekenleri yapmaya başlayayım. Aldığınız şey bir takvim aralığı değil, doğrudan sizin işinize harcanacak net mesai. 40 saati üç gün aralıksız çalışarak da kullanabiliriz, bilerek zamana yayıp bir yılda da bitirebiliriz — işin gerektirdiği neyse o. İşin ne kadar süreceğini tahmin etmeye değil, işi yapmaya vakit harcarım; harcadığım her saatin işinizde kalıcı bir karşılığı olur. Faydalı olduğunu düşündüğünüz sürece bu şekilde devam ederiz.

ÇALIŞMA BLOKLARI

## Neden aylık değil?
40 saat 1 hafta mı oluyor?

Aylık sabit ücrette iki taraf da yanlış yere bakar: siz sabit gidere, karşı taraf kaç tane daha böyle sözleşme bağlayabileceğine. Saat üzerinden çalışınca ikimizin de baktığı yer aynı olur — yapılan işin gerçek değeri. "Toplamda ne kadar tutar?" sorusunun peşinen net bir cevabı olmaması bu modelin doğal maliyeti, farkındayım. Ama sonuç üretmeyen bir yapıya aylarca sabit ücret ödemek yerine yalnızca işinize ayrılan nitelikli zamanı ödersiniz, o zamanın nereye gittiğini de baştan sona görürsünüz. Müşterilerimin benimle tekrar tekrar çalışmasının sebebi bu.

5saat10.000₺ + KDVsaat başı 2.000₺[Bu bloğu seç](https://wa.me/905496546489?text=Merhaba%2C%205%20saatlik%20%C3%A7al%C4%B1%C5%9Fma%20blo%C4%9Fu%20hakk%C4%B1nda%20bilgi%20almak%20istiyorum.)

10saat15.000₺ + KDVsaat başı 1.500₺[Bu bloğu seç](https://wa.me/905496546489?text=Merhaba%2C%2010%20saatlik%20%C3%A7al%C4%B1%C5%9Fma%20blo%C4%9Fu%20hakk%C4%B1nda%20bilgi%20almak%20istiyorum.)

20saat24.000₺ + KDVsaat başı 1.200₺[Bu bloğu seç](https://wa.me/905496546489?text=Merhaba%2C%2020%20saatlik%20%C3%A7al%C4%B1%C5%9Fma%20blo%C4%9Fu%20hakk%C4%B1nda%20bilgi%20almak%20istiyorum.)

40saat40.000₺ + KDVsaat başı 1.000₺[Bu bloğu seç](https://wa.me/905496546489?text=Merhaba%2C%2040%20saatlik%20%C3%A7al%C4%B1%C5%9Fma%20blo%C4%9Fu%20hakk%C4%B1nda%20bilgi%20almak%20istiyorum.)