Endüstriyel üretim tesislerinde, kalite kontrol laboratuvarlarında ve mühendislik departmanlarında her gün binlerce ölçüm verisi üretilir. CNC tezgahları, spektrometreler, çekme testi cihazları veya kurumsal ERP sistemleri ham verileri genellikle CSV, TXT ya da biçimlendirilmemiş ham tablolar halinde dışa aktarır. Bu verileri her hafta elle kopyalayıp Excel sayfalarına yapıştırmak, başlıkları tek tek boyamak, sınır değerleri kontrol edip renkli uyarılar eklemek ve formül yazmak hem saatler süren bir iş gücü kaybına hem de kritik insan hatalarına davetiye çıkarır.
Daha önce ofis verimliliği alanında paylaştığımız Excel Çevrimdışı Barkod ve QR Kod Oluşturma çözümlerimiz VBA makroları ile pratik sonuçlar üretirken; bağımsız, platformlar arası ve arka planda çalışan uçtan uca bir otomasyon zinciri kurmak için Python en güçlü silahtır. Hazırladığımız bu otomasyon scriptini auto-py-to-exe ile Python Dosyalarını EXE’ye Dönüştürme rehberimizi izleyerek ofisteki herhangi bir bilgisayarda Python kurulu olmasa dahi tek tıkla çalışan bir masaüstü aracına dönüştürebiliriz. Bu rehberde, openpyxl kütüphanesiyle kurumsal şablonlarda Excel raporu üretmeyi, veri doğrulama (Data Validation) kuralları tanımlamayı ve dinamik formüller inşa etmeyi adım adım öğreniyoruz.
Neden pandas Yerine Doğrudan openpyxl?
Veri analizi dünyasında Pandas kütüphanesi devasa veri kümelerini filtrelemek ve işlemek için vazgeçilmezdir. Ancak bir veri çerçevesini doğrudan df.to_excel() ile dışa aktardığınızda karşınıza renksiz, dar sütunlu, biçimlendirilmemiş ve formül içermeyen ham bir tablo çıkar. openpyxl ise Excel’in Office Open XML (XLSX) dosya yapısına doğrudan nüfuz ederek şu imkanları sunar:
- Kurumsal Tipografi ve Renkler: Yazı tipi (Font), boyut, hücre dolgusu (PatternFill) ve kenarlık (Border) stillerini piksel hassasiyetinde yönetme.
- Canlı Excel Formülleri: Statik değerler yerine hücrelere doğrudan dinamik formüller (
SUM,AVERAGE,COUNTIFvb.) yazarak dosya açıldığında Excel motorunun hesaplama yapmasını sağlama. - Veri Doğrulama (Data Validation): Hücrelere açılır liste (dropdown menu) veya belirli sayısal aralık kısıtlamaları koyarak kullanıcıların hatalı veri girişini engelleme.
- Koşullu Biçimlendirme (Conditional Formatting): Tolerans dışı ölçümleri veya hatalı parçaları otomatik olarak kırmızı/sarı renkle vurgulama.
- Otomatik Sütun Genişliği: İçeriğe göre sütunları optimize ederek
###taşma hatalarını ortadan kaldırma.
Geliştirme Ortamı ve Gerekli Kütüphanelerin Kurulumu
Projemiz için standart Python ortamına yalnızca openpyxl paketini eklememiz yeterlidir. Komut satırından aşağıdaki komutu çalıştırarak kurulumu tamamlayın:
pip install openpyxl
Sıfırdan Kurumsal Kalite Kontrol Raporu Üretim Scripti
Aşağıdaki script, talaşlı imalat veya döküm parçalarının ölçüm verilerini alarak, kurumsal lacivert başlık temasına sahip, tolerans dışı parçaları renklendiren ve otomatik özet istatistikler hesaplayan eksiksiz bir endüstriyel rapor üretir:
import os
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.utils import get_column_letter
from openpyxl.worksheet.datavalidation import DataValidation
def kurumsal_kalite_raporu_olustur(dosya_adi="Endustriyel_Kalite_Raporu.xlsx"):
# Yeni bir çalisma kitabi baslat
wb = Workbook()
ws = wb.active
ws.title = "Kalite Kontrol Verileri"
# Kılavuz çizgilerini açık tut
ws.views.sheetView[0].showGridLines = True
# --- Kurumsal Renk ve Stil Sabitleri ---
navy_header_fill = PatternFill(start_color="1B365D", end_color="1B365D", fill_type="solid")
header_font = Font(name="Segoe UI", size=11, bold=True, color="FFFFFF")
title_font = Font(name="Segoe UI", size=16, bold=True, color="1B365D")
meta_font = Font(name="Segoe UI", size=10, italic=True, color="595959")
bold_cell_font = Font(name="Segoe UI", size=10, bold=True, color="000000")
data_font = Font(name="Segoe UI", size=10, color="000000")
# Kenarlık Stilleri
thin_border = Border(
left=Side(style="thin", color="D9D9D9"),
right=Side(style="thin", color="D9D9D9"),
top=Side(style="thin", color="D9D9D9"),
bottom=Side(style="thin", color="D9D9D9")
)
total_top_border = Side(style="thin", color="000000")
total_bottom_border = Side(style="double", color="000000")
summary_border = Border(top=total_top_border, bottom=total_bottom_border)
# Durum Dolguları (Koşullu Görsel Vurgu)
pass_fill = PatternFill(start_color="E2EFDA", end_color="E2EFDA", fill_type="solid") # Açık Yeşil
fail_fill = PatternFill(start_color="FCE4D6", end_color="FCE4D6", fill_type="solid") # Açık Kırmızı
warn_fill = PatternFill(start_color="FFF2CC", end_color="FFF2CC", fill_type="solid") # Açık Sarı
# Hizalama Seçenekleri
center_align = Alignment(horizontal="center", vertical="center")
left_align = Alignment(horizontal="left", vertical="center")
right_align = Alignment(horizontal="right", vertical="center")
# --- 1. Rapor Başlık Bloğu ---
ws.merge_cells("A1:F1")
ws["A1"] = "KARDÖKMAK A.Ş. — MEKANİK İMALAT KALİTE DENETİM RAPORU"
ws["A1"].font = title_font
ws["A1"].alignment = left_align
ws.row_dimensions[1].height = 30
ws["A2"] = "Denetim Tarihi: 2026-09-23 | Vardiya: 1. Vardiya | Rapor Sorumlusu: Kalite Güvence Birimi"
ws["A2"].font = meta_font
ws.row_dimensions[2].height = 18
# --- 2. Tablo Başlıkları ---
headers = [
"Parça Kodu",
"Nominal Ölçü (mm)",
"Tolerans (±mm)",
"Ölçülen Değer (mm)",
"Sapma (mm)",
"Kalite Kararı"
]
start_row = 4
ws.row_dimensions[start_row].height = 25
for col_idx, header_text in enumerate(headers, start=1):
cell = ws.cell(row=start_row, column=col_idx, value=header_text)
cell.fill = navy_header_fill
cell.font = header_font
cell.alignment = center_align
# --- 3. Örnek İmalat Ölçüm Verileri ---
ham_veriler = [
("AKS-4011", 120.00, 0.05, 120.02),
("AKS-4012", 120.00, 0.05, 120.04),
("AKS-4013", 120.00, 0.05, 120.09), # Tolerans Dışı (Red)
("AKS-4014", 120.00, 0.05, 119.98),
("AKS-4015", 120.00, 0.05, 120.01),
("AKS-4016", 120.00, 0.05, 120.06), # Şartlı Kabul Sınırı
("AKS-4017", 120.00, 0.05, 119.95),
("AKS-4018", 120.00, 0.05, 120.00),
]
current_row = start_row + 1
for parca, nominal, tol, olculen in ham_veriler:
ws.cell(row=current_row, column=1, value=parca).alignment = center_align
ws.cell(row=current_row, column=2, value=nominal).number_format = "0.00"
ws.cell(row=current_row, column=3, value=tol).number_format = "0.00"
ws.cell(row=current_row, column=4, value=olculen).number_format = "0.00"
# Dinamik Excel Sapma Formülü: Ölçülen - Nominal
sapma_formulu = f"=D{current_row}-B{current_row}"
ws.cell(row=current_row, column=5, value=sapma_formulu).number_format = "+0.00;-0.00;0.00"
# Dinamik Excel Karar Formülü
karar_formulu = f'=IF(ABS(E{current_row})<=C{current_row},"UYGUN",IF(ABS(E{current_row})<=(C{current_row}*1.5),"ŞARTLI KABUL","RED"))'
karar_cell = ws.cell(row=current_row, column=6, value=karar_formulu)
karar_cell.alignment = center_align
# Hücreleri Stillendir
for c in range(1, 7):
cell = ws.cell(row=current_row, column=c)
cell.font = data_font
cell.border = thin_border
if c in (2, 3, 4, 5):
cell.alignment = right_align
# Ön Koşullu Renk Ataması (Hızlı Görsel Analiz)
sapma_degeri = round(abs(olculen - nominal), 4)
if sapma_degeri <= tol:
karar_cell.fill = pass_fill
elif sapma_degeri <= (tol * 1.5):
karar_cell.fill = warn_fill
else:
karar_cell.fill = fail_fill
karar_cell.font = Font(name="Segoe UI", size=10, bold=True, color="C00000")
ws.row_dimensions[current_row].height = 20
current_row += 1
# --- 4. İstatistik ve Toplam Formülleri Satırı ---
end_data_row = current_row - 1
ws.row_dimensions[current_row].height = 22
ws.cell(row=current_row, column=1, value="ORTALAMA / GENEL TOPLAM").font = bold_cell_font
ws.cell(row=current_row, column=1).alignment = left_align
# Ortalama Ölçülen Değer Formülü
avg_cell = ws.cell(row=current_row, column=4, value=f"=AVERAGE(D5:D{end_data_row})")
avg_cell.font = bold_cell_font
avg_cell.number_format = "0.000"
avg_cell.alignment = right_align
# Ortalama Sapma Formülü
avg_sapma = ws.cell(row=current_row, column=5, value=f"=AVERAGE(E5:E{end_data_row})")
avg_sapma.font = bold_cell_font
avg_sapma.number_format = "+0.000;-0.000;0.000"
avg_sapma.alignment = right_align
# Uygunluk Oranı Metni
uygunluk_cell = ws.cell(row=current_row, column=6, value=f'=COUNTIF(F5:F{end_data_row},"UYGUN")&" / "&COUNTA(F5:F{end_data_row})')
uygunluk_cell.font = bold_cell_font
uygunluk_cell.alignment = center_align
for c in range(1, 7):
ws.cell(row=current_row, column=c).border = summary_border
# --- 5. Veri Doğrulama (Açılır Liste Kuralı Tanımlama) ---
dv = DataValidation(type="list", formula1='"UYGUN,ŞARTLI KABUL,RED"', allow_blank=False)
dv.error ='Lütfen sadece UYGUN, ŞARTLI KABUL veya RED değerlerinden birini seçin.'
dv.errorTitle = 'Geçersiz Kalite Kararı'
dv.prompt = 'Kalite sonucunu listeden seçebilirsiniz.'
dv.promptTitle = 'Karar Girişi'
ws.add_data_validation(dv)
dv.add(f"F5:F{end_data_row}")
# --- 6. Otomatik Sütun Genişliği Hesaplama ---
for col in ws.columns:
max_len = 0
col_letter = get_column_letter(col[0].column)
for cell in col:
# Birleştirilmiş başlık hücresini sütun genişliği hesabına katma
if cell.row == 1 and cell.column != 1:
continue
if cell.value:
# Formül ise tahmini uzunluk ver
deger_str = str(cell.value)
if deger_str.startswith("="):
deger_str = "12345678"
max_len = max(max_len, len(deger_str))
ws.column_dimensions[col_letter].width = max(max_len + 5, 14)
# Dosyayı Kaydet
wb.save(dosya_adi)
print(f"Rapor basariyla olusturuldu: {dosya_adi}")
if __name__ == "__main__":
kurumsal_kalite_raporu_olustur()
Dinamik Formüller ve Excel Fonksiyonlarının Enjeksiyonu
Yukarıdaki scriptte dikkat edilmesi gereken en mühim teknik detay, sapma ve karar sütunlarına sabit sayısal sonuçlar yerine doğrudan Excel formül dizgelerinin yazılmasıdır. Örneğin:
# Hücreye Excel formülü atama
sapma_formulu = f"=D{current_row}-B{current_row}"
karar_formulu = f'=IF(ABS(E{current_row})<=C{current_row},"UYGUN",IF(ABS(E{current_row})<=(C{current_row}*1.5),"ŞARTLI KABUL","RED"))'
Bu yaklaşım sayesinde kalite mühendisi veya operatör Excel dosyasını açıp ölçülen değerde bir düzeltme yaptığında, sapma ve kalite kararı otomatik olarak yeniden hesaplanır. Rapor statik bir çıktı olmaktan çıkıp etkileşimli bir mühendislik aracına dönüşür.
Veri Doğrulama (Data Validation) ile Kullanıcı Hatalarını Engelleme
Raporu dolduracak saha çalışanlarının tabloya "KABUL", "OK", "UYGUNDUR", "HAYIR" gibi standart dışı metinler yazmasını önlemek için DataValidation sınıfı kullanılır. Scriptimizde tanımladığımız açılır menü kuralı, Excel'in veri doğrulama motorunu tetikleyerek hücre tıklandığında yalnızca belirlenen seçenekleri sunar ve farklı bir giriş yapıldığında uyarı penceresi fırlatır.
Sütun Genişliği Optimizasyonu ve `###` Hatasının Önlenmesi
Excel kullanıcılarının en çok canını sıkan durumlardan biri, sayısal bir değerin sütun genişliğini aşması durumunda hücrede beliren ### gösterimidir. Scriptin sonunda yer alan döngü, her sütundaki en uzun metni (veya formül karakterini) tarar ve sütun genişliğini otomatik olarak dinamik biçimde boyutlandırır.
Scripti Tek Tıkla Çalışan Masaüstü EXE Aracına Dönüştürme
Hazırladığınız bu Python scriptini üretim sahasındaki veya idari birimlerdeki çalışma arkadaşlarınıza dağıtırken onların bilgisayarına Python veya kütüphane kurmak zorunda değilsiniz. Daha önce detaylandırdığımız auto-py-to-exe ile Python Dosyalarını EXE'ye Dönüştürme yöntemini kullanarak:
- Terminalden
auto-py-to-exekomutunu çalıştırın. - Script dosyanızı seçip One File (Tek Dosya) ve Window Based (Konsolsuz) seçeneklerini işaretleyin.
- Üretilen
.exedosyasını çift tıklayan her personel, anında klasöründe biçimlendirilmiş taze Excel kalite raporunu görecektir.
Kaynaklar ve Referanslar
Bu makale hazırlanırken aşağıdaki kaynaklardan ve resmi teknik dökümantasyonlardan faydalanılmıştır:
- openpyxl Official Documentation - Read the Docs
- Real Python - Working With Excel Spreadsheets in Python Using openpyxl
- Karakavuz.com - auto-py-to-exe ile Python Dosyalarını EXE'ye Dönüştürme Rehberi
- Karakavuz.com - Excel ve PC Otomasyonu Çözümleri
- Karakavuz.com - Mekanik ve Geometrik İmalat Hesaplama Araçları




