sửa code python (5 người xem)

Người dùng đang xem chủ đề này

Tôi tuân thủ nội quy khi đăng bài
Có

Hoale85

Thành viên chính thức
Tham gia
2/8/24
Bài viết
99
Được thích
7
Em nhờ anh chị sửa giúp em code sau với ạ: đoạn chỗ kiểm tra checkbok:
import cv2
import numpy as np
import os
import glob
import time
import traceback
import gc
import ctypes

# =========================================================
# 0. CỐ ĐỊNH DPI TRƯỚC KHI NẠP PYAUTOGUI
# =========================================================

try:
ctypes.windll.shcore.SetProcessDpiAwareness(2)
except Exception:
try:
ctypes.windll.user32.SetProcessDPIAware()
except Exception:
pass

import pyautogui
import pyperclip
import win32gui
import win32con
import win32com.client as win32

import cv2
import numpy as np


# =========================================================
# 1. CẤU HÌNH
# =========================================================

pyautogui.FAILSAFE = False
pyautogui.PAUSE = 0.3

URL_DANG_NHAP = (
"https://amisapp.misa.vn/login/?href="
"L0FQSVMvSW50ZWdyYXRpb25BUEkvYXBwL3JlZGlyZWN0L0FjY291bnRpbmc="
)

URL_BAO_CAO = (
"https://actapp.misa.vn/app/RP/ReportList/"
"RPDynamicViewer/GLBookDetailPaymentByAccountNumber"
)

DOWNLOAD_DIR = r"C:\Users\admin\Downloads"
FILE_TONG = r"D:\Hoa lv\Kiem soat\128-341.xlsm"

# KÍCH THƯỚC MÀN HÌNH CHUẨN
CHUAN_RONG = 1920
CHUAN_CAO = 1200

MAN_HINH_KHOI_DAU = pyautogui.size()

TY_LE_X = MAN_HINH_KHOI_DAU.width / CHUAN_RONG
TY_LE_Y = MAN_HINH_KHOI_DAU.height / CHUAN_CAO

print("=" * 65)
print("THÔNG TIN MÀN HÌNH")
print("Chiều rộng:", MAN_HINH_KHOI_DAU.width)
print("Chiều cao:", MAN_HINH_KHOI_DAU.height)
print("Tỷ lệ X:", TY_LE_X)
print("Tỷ lệ Y:", TY_LE_Y)
print("=" * 65)

# Thời gian chờ
CHO_MO_CHROME = 3
CHO_TAI_TRANG = 8
CHO_GOI_Y_128 = 2
CHO_TAI_FILE = 120

# Ảnh chụp checkbox
THU_MUC_CODE = os.path.dirname(os.path.abspath(__file__))

FILE_ANH_CHECKBOX = os.path.join(
THU_MUC_CODE,
"checkbox_screenshot.png"
)

FILE_ANH_SAU_CHECKBOX = os.path.join(
THU_MUC_CODE,
"checkbox_screenshot_after.png"
)

# Ngưỡng màu nhận diện viền xanh trong ảnh HSV
# OpenCV Hue có giá trị từ 0 đến 179
BLUE_H_MIN = 90
BLUE_H_MAX = 135
BLUE_S_MIN = 65
BLUE_V_MIN = 65

# Ngưỡng nhận diện dấu tích xanh bên trong checkbox
GREEN_H_MIN = 35
GREEN_H_MAX = 90
GREEN_S_MIN = 55
GREEN_V_MIN = 55

# Kích thước dự kiến của khung viền xanh quanh checkbox
KHUNG_MIN = 12
KHUNG_MAX = 70


# =========================================================
# 2. KIỂM TRA VÀ CỐ ĐỊNH TỌA ĐỘ
# =========================================================

def kiem_tra_man_hinh():

man_hinh_hien_tai = pyautogui.size()

if (
man_hinh_hien_tai.width != MAN_HINH_KHOI_DAU.width
or man_hinh_hien_tai.height != MAN_HINH_KHOI_DAU.height
):
raise Exception(
"ĐỘ PHÂN GIẢI MÀN HÌNH ĐÃ THAY ĐỔI!\n"
f"Lúc chạy: {MAN_HINH_KHOI_DAU.width}x{MAN_HINH_KHOI_DAU.height}\n"
f"Hiện tại: {man_hinh_hien_tai.width}x{man_hinh_hien_tai.height}\n"
"Vui lòng giữ nguyên độ phân giải màn hình."
)


def toa_do(x, y):

kiem_tra_man_hinh()

px = int(x * TY_LE_X)
py = int(y * TY_LE_Y)

return px, py


def click_xy(x, y, so_lan=1):

px, py = toa_do(x, y)

pyautogui.moveTo(px, py, duration=0.2)

pyautogui.click(
px,
py,
clicks=so_lan,
interval=0.15
)


def nhap_url(url):

pyautogui.hotkey("ctrl", "l")
time.sleep(0.3)

pyperclip.copy(url)
pyautogui.hotkey("ctrl", "v")

pyautogui.press("enter")


def dan_chu(chu):

pyperclip.copy(str(chu))
pyautogui.hotkey("ctrl", "v")


# =========================================================
# 3. DANH SÁCH CÔNG TY
# =========================================================

DS_CONG_TY = [
{
"ten": "KHOÁNG SẢN VŨ GIA YÊN BÁI",
"tab": 4,
"sheet": "128-VG_YENBAI"
},
{
"ten": "CÔNG TY CỔ PHẦN CHĂN NUÔI CÔNG NGHỆ CAO VACA MAXI",
"tab": 3,
"sheet": "128-VACA"
},
{
"ten": "CÔNG TY CỔ PHẦN CÔNG NGHỆ EMBERA",
"tab": 3,
"sheet": "128-EMBERA_TECH"
},
{
"ten": "CÔNG TY CỔ PHẦN TẬP ĐOÀN EMBERA",
"tab": 3,
"sheet": "128-EMBERA_TD"
},
{
"ten": "CÔNG TY CỔ PHẦN TẬP ĐOÀN MIT VIỆT NAM",
"tab": 6,
"sheet": "128-MIT"
}
]


# =========================================================

# =========================================================

def kiem_tra_checkbox():
print("Đang chuyển đến ô Check Book...")

# 1. Tab đúng 3 lần sau khi Enter 128
for i in range(3):
pyautogui.press('tab')
time.sleep(0.3)

# Chờ giao diện ổn định hoàn toàn sau khi di chuyển tiêu điểm Tab
time.sleep(0.6)

# 2. SỬ DỤNG TỌA ĐỘ TUYỆT ĐỐI BẠN ĐÃ ĐO THỰC TẾ (CỐ ĐỊNH)
x_chuan = 614
y_chuan = 364

# Lấy mã màu RGB trực tiếp tại tọa độ này từ màn hình
# Định dạng trả về là một bộ 3 số (R, G, B)
rgb_color = pyautogui.pixel(x_chuan, y_chuan)
r, g, b = rgb_color[0], rgb_color[1], rgb_color[2]

print(f" Màu sắc thực tế đo được tại vị trí (614, 364) là: R={r}, G={g}, B={b}")

# 3. KHÓA CỨNG LOGIC BẢO VỆ DỰA TRÊN MÀU SẮC THỰC TẾ
# Dấu tích xanh lá cây của MISA có đặc điểm: Kênh Green (Xanh lá) lớn hẳn so với Red và Blue
# Đồng thời kênh Red của màu xanh lá cây này rất thấp (thường < 100)
if g > 130 and r < 120:
# TRẠNG THÁI ĐÃ CÓ TÍCH XANH (NHƯ HÌNH BẠN GỬI) -> BỎ QUA 100%
print("====== KẾT QUẢ: ĐÃ CÓ DẤU TÍCH V XANH -> BỎ QUA HOÀN TOÀN (KHÔNG ẤN PHÍM CÁCH) ======")
# Nhánh này hoàn toàn trống rỗng, không chứa bất kỳ mã lệnh tương tác bàn phím nào cả

else:
# TRẠNG THÁI Ô TRỐNG TRẮNG (Hoặc không phải màu tích xanh) -> TIẾN HÀNH TÍCH CHỌN
print("====== KẾT QUẢ: Ô ĐANG TRỐNG -> TIẾN HÀNH NHẤN SPACE ĐỂ TÍCH CHỌN ======")
pyautogui.press('space')

return True


# =========================================================
# 5. TÌM VÀ MỞ TAB CHROME
# =========================================================

def lay_danh_sach_cua_so_chrome():

ket_qua = []

def callback(hwnd, extra):

try:
if not win32gui.IsWindowVisible(hwnd):
return True

ten = win32gui.GetWindowText(hwnd)

if "Chrome" in ten:
ket_qua.append(hwnd)

except Exception:
pass

return True

win32gui.EnumWindows(callback, None)

return ket_qua


def lay_cua_so_chrome_hien_tai():

hwnd = win32gui.GetForegroundWindow()

if hwnd and win32gui.IsWindow(hwnd):

ten = win32gui.GetWindowText(hwnd)

if "Chrome" in ten:
return hwnd

windows = lay_danh_sach_cua_so_chrome()

if not windows:
raise Exception("Không tìm thấy cửa sổ Chrome đang mở.")

return windows[0]


def kich_hoat_chrome(hwnd):

kiem_tra_man_hinh()

if hwnd and win32gui.IsWindow(hwnd):

win32gui.ShowWindow(
hwnd,
win32con.SW_MAXIMIZE
)

win32gui.SetForegroundWindow(hwnd)

time.sleep(1)

pyautogui.hotkey("ctrl", "0")

time.sleep(1)

kiem_tra_man_hinh()


def mo_chrome_misa():

print("Đang mở tab Chrome MISA mới...")

hwnd = lay_cua_so_chrome_hien_tai()

kich_hoat_chrome(hwnd)

pyautogui.hotkey("ctrl", "t")

time.sleep(1)

nhap_url(URL_DANG_NHAP)

time.sleep(CHO_MO_CHROME)

print("Đã mở trang đăng nhập MISA.")

return hwnd


def dong_chrome_misa(hwnd):

if not hwnd or not win32gui.IsWindow(hwnd):

print("Không tìm thấy cửa sổ Chrome để đóng tab.")

return

print("Đang đóng 2 tab Chrome MISA mới...")

kich_hoat_chrome(hwnd)

pyautogui.hotkey("ctrl", "w")

time.sleep(1)

pyautogui.hotkey("ctrl", "w")

time.sleep(2)

print("Đã đóng 2 tab Chrome MISA.")


# =========================================================
# 6. CHỌN CÔNG TY
# =========================================================

def chon_cong_ty(ten_cong_ty):

print("Đang chọn công ty:", ten_cong_ty)

time.sleep(3)

click_xy(1828, 131)

time.sleep(3)

click_xy(1804, 417)

time.sleep(2)

click_xy(1816, 411)

time.sleep(2)

click_xy(769, 475)

pyautogui.hotkey("ctrl", "a")

dan_chu(ten_cong_ty)

time.sleep(5)

click_xy(636, 532)

time.sleep(1)

click_xy(1258, 863)

time.sleep(1)

print("Đã chọn công ty.")


# =========================================================
# 7. VÀO KẾ TOÁN VÀ MỞ BÁO CÁO
# =========================================================

def vao_bao_cao():

print("Đang vào phân hệ Kế toán...")

time.sleep(2)

click_xy(32, 137)

time.sleep(1)

dan_chu("kế toán")

time.sleep(1)

click_xy(145, 283)

time.sleep(3)

nhap_url(URL_BAO_CAO)

time.sleep(CHO_TAI_TRANG)

print("Đã mở báo cáo.")


# =========================================================
# 8. CHỌN THAM SỐ VÀ KIỂM TRA CHECKBOX
# =========================================================

def chon_tham_so(so_lan_tab):

print("Đang chọn tham số báo cáo...")

click_xy(1746, 204)

time.sleep(2)

for i in range(so_lan_tab):

pyautogui.press("tab")

time.sleep(0.3)

pyautogui.hotkey("ctrl", "a")

dan_chu("128")

time.sleep(CHO_GOI_Y_128)

pyautogui.press("enter")

time.sleep(1)

# Sau Enter 128, Tab đúng 3 lần đến checkbox
kiem_tra_checkbox()

print("Đã hoàn thành chọn tham số.")


# =========================================================
# 9. KIỂM TRA FILE DOWNLOAD
# =========================================================

def lay_trang_thai_download():

trang_thai = {}

for duoi in ("*.xlsx", "*.xls", "*.xlsm"):

for file in glob.glob(
os.path.join(DOWNLOAD_DIR, duoi)
):

try:

trang_thai[file] = (
os.path.getmtime(file),
os.path.getsize(file)
)

except Exception:
pass

return trang_thai


def cho_file_tai_xong(trang_thai_cu, timeout=120):

print("Đang chờ tải Excel...")

bat_dau = time.time()

file_on_dinh = None
dem_on_dinh = 0
kich_thuoc_cu = -1

while time.time() - bat_dau < timeout:

dang_tai = glob.glob(
os.path.join(DOWNLOAD_DIR, "*.crdownload")
)

if dang_tai:

time.sleep(1)

continue

danh_sach_moi = []

for duoi in ("*.xlsx", "*.xls", "*.xlsm"):

for file in glob.glob(
os.path.join(DOWNLOAD_DIR, duoi)
):

try:

mtime = os.path.getmtime(file)

size = os.path.getsize(file)

thong_tin_cu = trang_thai_cu.get(file)

if (
thong_tin_cu is None
or mtime > thong_tin_cu[0]
or size != thong_tin_cu[1]
):

danh_sach_moi.append(
(mtime, file, size)
)

except Exception:
pass

if danh_sach_moi:

danh_sach_moi.sort(reverse=True)

_, file_hien_tai, kich_thuoc = danh_sach_moi[0]

if (
file_hien_tai == file_on_dinh
and kich_thuoc == kich_thuoc_cu
):

dem_on_dinh += 1

else:

file_on_dinh = file_hien_tai

kich_thuoc_cu = kich_thuoc

dem_on_dinh = 0

if dem_on_dinh >= 3 and kich_thuoc > 0:

print("Đã tải xong:", file_on_dinh)

return file_on_dinh

time.sleep(1)

raise TimeoutError(
"Quá thời gian chờ tải file Excel."
)


# =========================================================
# 10. TẢI BÁO CÁO
# =========================================================

def tai_bao_cao():

print("Đang thực hiện tải báo cáo...")

trang_thai_cu = lay_trang_thai_download()

click_xy(1768, 1108)

time.sleep(3)

click_xy(1703, 276)

time.sleep(2)

click_xy(1252, 868)

time.sleep(2)

click_xy(1130, 313)

time.sleep(15)

file_excel = cho_file_tai_xong(
trang_thai_cu,
CHO_TAI_FILE
)

return file_excel


# =========================================================
# 11. MỞ FILE EXCEL Ổ D, DÁN DỮ LIỆU, LƯU VÀ ĐÓNG
# =========================================================

def dan_du_lieu_vao_excel(file_nguon, ten_sheet):

print("\nĐANG MỞ EXCEL ĐỂ DÁN DỮ LIỆU")

print("File nguồn:", file_nguon)

print("File đích:", FILE_TONG)

print("Sheet đích:", ten_sheet)

if not os.path.exists(file_nguon):

raise FileNotFoundError(
"Không tìm thấy file Excel vừa tải."
)

if not os.path.exists(FILE_TONG):

raise FileNotFoundError(
"Không tìm thấy file tổng hợp ở ổ D: " + FILE_TONG
)

excel = None

wb_nguon = None

wb_tong = None

try:

excel = win32.DispatchEx("Excel.Application")

excel.Visible = True

excel.DisplayAlerts = False

excel.ScreenUpdating = True

excel.EnableEvents = False

print("Đang mở file Excel vừa tải...")

wb_nguon = excel.Workbooks.Open(
os.path.abspath(file_nguon),
ReadOnly=True
)

ws_nguon = wb_nguon.Worksheets(1)

time.sleep(2)

print("Đang mở file tổng hợp ở ổ D...")

wb_tong = excel.Workbooks.Open(
os.path.abspath(FILE_TONG)
)

excel.Visible = True

excel.WindowState = -4137

wb_tong.Activate()

time.sleep(2)

print("Đang hiện các sheet ẩn...")

for ws in wb_tong.Worksheets:

if ws.Visible != -1:

ws.Visible = -1

try:

ws_dich = wb_tong.Worksheets(ten_sheet)

except Exception:

raise Exception(
"Không tìm thấy sheet đích: " + ten_sheet
)

ws_dich.Activate()

time.sleep(1)

print("Đang xóa dữ liệu cũ...")

ws_dich.Cells.Clear()

vung_nguon = ws_nguon.UsedRange

print("Đang dán dữ liệu...")

vung_nguon.Copy(
Destination=ws_dich.Range("A1")
)

time.sleep(2)

print("Đang lưu file tổng hợp...")

wb_tong.Save()

time.sleep(2)

print("ĐÃ LƯU THÀNH CÔNG:", ten_sheet)

finally:

if wb_nguon is not None:

try:
wb_nguon.Close(SaveChanges=False)
except Exception:
pass

if wb_tong is not None:

try:
wb_tong.Close(SaveChanges=True)
except Exception:
pass

if excel is not None:

try:
excel.DisplayAlerts = False
excel.Quit()
except Exception:
pass

wb_nguon = None

wb_tong = None

excel = None

gc.collect()

time.sleep(1)

print("ĐÃ ĐÓNG EXCEL HOÀN TOÀN.")


# =========================================================
# 12. XỬ LÝ TỪNG CÔNG TY
# =========================================================

def xu_ly_cong_ty(cong_ty):

ten_cong_ty = cong_ty["ten"]

so_lan_tab = cong_ty["tab"]

ten_sheet = cong_ty["sheet"]

hwnd_misa = None

print("\n")

print("=" * 65)

print("BẮT ĐẦU:", ten_cong_ty)

print("=" * 65)

try:

hwnd_misa = mo_chrome_misa()

kich_hoat_chrome(hwnd_misa)

chon_cong_ty(ten_cong_ty)

vao_bao_cao()

chon_tham_so(so_lan_tab)

file_excel = tai_bao_cao()

if not file_excel or not os.path.exists(file_excel):

raise Exception(
"Không tìm thấy file Excel sau khi tải."
)

dan_du_lieu_vao_excel(
file_excel,
ten_sheet
)

# Chỉ đóng Chrome sau khi Excel đã lưu và đóng xong
kich_hoat_chrome(hwnd_misa)

dong_chrome_misa(hwnd_misa)

print("HOÀN THÀNH:", ten_cong_ty)

return True

except Exception as e:

print("\nLỖI KHI XỬ LÝ:", ten_cong_ty)

print("Chi tiết:", str(e))

traceback.print_exc()

print("Giữ nguyên tab Chrome để kiểm tra lỗi.")

return False


# =========================================================
# 13. CHẠY TOÀN BỘ DANH SÁCH
# =========================================================

def main():

print("\nBẮT ĐẦU CHẠY DANH SÁCH CÔNG TY")

print("File tổng hợp:", FILE_TONG)

print(
"Màn hình đang sử dụng:",
MAN_HINH_KHOI_DAU.width,
"x",
MAN_HINH_KHOI_DAU.height
)

if not os.path.exists(FILE_TONG):

print("KHÔNG TÌM THẤY FILE TỔNG HỢP Ở Ổ D.")

return

if not os.path.isdir(DOWNLOAD_DIR):

print("KHÔNG TÌM THẤY THƯ MỤC DOWNLOAD.")

return

kiem_tra_man_hinh()

thanh_cong = 0

that_bai = 0

for i, cong_ty in enumerate(DS_CONG_TY, start=1):

print("\n")

print("#" * 65)

print(
"CÔNG TY",
i,
"/",
len(DS_CONG_TY)
)

print("#" * 65)

ket_qua = xu_ly_cong_ty(cong_ty)

if ket_qua:

thanh_cong += 1

else:

that_bai += 1

time.sleep(2)

print("\n")

print("=" * 65)

print("ĐÃ KẾT THÚC TOÀN BỘ CHƯƠNG TRÌNH")

print("Thành công:", thanh_cong)

print("Thất bại:", that_bai)

print("=" * 65)


# =========================================================
# 14. KHỞI CHẠY
# =========================================================

if __name__ == "__main__":

try:

main()

except Exception:

print("\nLỖI CHƯƠNG TRÌNH:")

traceback.print_exc()

finally:

input("\nNhấn ENTER để đóng chương trình...")
đoạn check book ko dùng tọa độ mà kiểm tra tại vị trí tab 3 lần sau khi enter 128 để đảm bảo luôn chọn tất cả. nếu đã chọn tất cả thì bỏ qua1794134638462.png1794134591535.png
 

Bài viết mới nhất

Back
Top Bottom