Home > other >  Changing row in Excel file when row is filled
Changing row in Excel file when row is filled

Time:04-27

enter image description here

I'm coding a simple timer using Tkinter. I want my code to save the time the timer is showing when the stop button is activated in an Excel file. The timer works fine but the data is stored in just one row in the Excel file. I want it to change row when e.g. 5 cells in a row is filled.

I've been trying using conditional for loop. E.G. I tried to increment min_row with 1 every time the cell values is not None but it's not working.

Could someone tell me what I'm doing wrong?

# ***** IMPORTS *****
import tkinter as tk
from openpyxl import Workbook
from openpyxl import load_workbook



running = False
# time variables initially set to 0
hours, minutes, seconds, total_time = 0, 0, 0, 0

def start():
    global running
    if not running:
        update()
        running = True

# pause function
def pause():
    global running
    if running:
        # cancel updating of time using after_cancel()
        stopwatch_label.after_cancel(update_time)
        running = False

# reset function
def reset():
    global running
    if running:
        # cancel updating of time using after_cancel()
        stopwatch_label.after_cancel(update_time)
        running = False
    # set variables back to zero
    global hours, minutes, seconds
    hours, minutes, seconds = 0, 0, 0
    # set label back to zero
    stopwatch_label.config(text='00:00:00')

# update stopwatch function
def update():
    # update seconds with (addition) compound assignment operator
    global hours, minutes, seconds, total_time
    seconds  = 1
    total_time  = 1
    if seconds == 60:
        minutes  = 1
        seconds = 0
    if minutes == 60:
        hours  = 1
        minutes = 0
    # format time to include leading zeros
    hours_string = f'{hours}' if hours > 9 else f'0{hours}'
    minutes_string = f'{minutes}' if minutes > 9 else f'0{minutes}'
    seconds_string = f'{seconds}' if seconds > 9 else f'0{seconds}'
    # update timer label after 1000 ms (1 second)
    stopwatch_label.config(text=hours_string   ':'   minutes_string   ':'   seconds_string)

    global update_time
    update_time = stopwatch_label.after(1000, update)
    
def excel_update():
    dest_filename = r"C:\Users\abbas\OneDrive\Desktop\Prog\Flex\tider.xlsx"
    #dest_filename = r"C:\Users\abbas\OneDrive\Desktop\Prog\Flex\test.xlsx"
    wb = load_workbook(dest_filename)
    ws = wb.active
    next_row = 1
    
    cell_range = ws.iter_rows(min_row=next_row, max_row=3, max_col=2)
    #cell_range = ws["A1":"B3"]
    
    for rows in cell_range:        
        for columns in rows:
            if columns.value[columns] is None:
                columns.value[columns] = total_time
                          
        break
    
    wb.save(dest_filename)   
    
# ***** WIDGETS *****
# create main window
root = tk.Tk()
#root.geometry('450x200')
root.resizable(width=False, height=False)
root.title('Stopwatch')

# label to display time
stopwatch_label = tk.Label(text='00:00:00', font=('Arial', 20))
stopwatch_label.pack()

# start, pause, reset, stop buttons
start_button = tk.Button(text='start', height=3, width=5, font=('Arial', 10), command=start)
start_button.pack(side=tk.LEFT)

stop_button = tk.Button(text='stop', height=3, width=5, font=('Arial', 10), command=lambda:[root.quit(), excel_update()])
stop_button.pack(side=tk.LEFT)

pause_button = tk.Button(text='pause', height=3, width=5, font=('Arial', 10), command=pause)
pause_button.pack(side=tk.LEFT)

reset_button = tk.Button(text='reset', height=3, width=5, font=('Arial', 10), command=reset)
reset_button.pack(side=tk.LEFT)

# ***** MAINLOOP *****
root.mainloop()

CodePudding user response:

Based on the code in your updated question, I think changing the excel_update() function as shown below will make it do what you want.

It searches through the columns of the rows from min_row to max_row looking for an empty cell. If it finds one it assigns the time value to it and raises a StopIteration exception to break out of the nested for loops and terminate the search. The exception is then simply ignored since it's part of normal processing.

from tkinter.messagebox import showerror

def excel_update():
def excel_update():
    dest_filename = r"C:\Users\abbas\OneDrive\Desktop\Prog\Flex\tider.xlsx"
    wb = load_workbook(dest_filename)
    ws = wb.active

    # Put value in next empty cell in specified region (if one exists).
    try:
        for row in ws.iter_rows(min_row=1, max_row=3, max_col=3):
            for cell in row:
                if cell.value is None:
                    cell.value = total_time
                    raise StopIteration
        else:  # No exception raised.
            showerror('Error!', 'No empty cells left for storing timer time!')
    except StopIteration:
        pass

    wb.save(dest_filename)  # Update file.

  • Related