勤務表半自動更新ツール(Python)

update_attendance_sheet.py

# update_attendance.py
#! /usr/bin/env python

from calendar import week
from encodings import utf_8
from math import nan
import os
from symbol import pass_stmt
import sys
from time import time
from unittest import result
import pandas as pd
from ast import JoinedStr
from distutils.command import config
from ntpath import join
import configparser
import datetime
import re

class MemberType():
   PROPER = 0
   PARTNER = 1

class Member:
   def __init__(self, member_type:MemberType):
       self.member_type = member_type # 0:Proper, 1:Partner

   def round_time(self, update_list:list, update_idx:int, time_table_list:list, time_table_idx:int, week_list:list):
       if time_table_idx%5 == 0:
           update_list[update_idx][week_list[0]] = time_table_list[time_table_idx]
       elif time_table_idx%5 == 1:
           update_list[update_idx][week_list[1]] = time_table_list[time_table_idx]
       elif time_table_idx%5 == 2:
           update_list[update_idx][week_list[2]] = time_table_list[time_table_idx]
       elif time_table_idx%5 == 3:
           update_list[update_idx][week_list[3]] = time_table_list[time_table_idx]
       elif time_table_idx%5 == 4:
           update_list[update_idx][week_list[4]] = time_table_list[time_table_idx]
       else:
           pass

   def remove_ravel(self, update_list:list, update_idx:int, week_list:list):
       for i in range(len(week_list)):
           if type(update_list[update_idx][week_list[i]]) == datetime.datetime:
               pass
           elif type(update_list[update_idx][week_list[i]]) == float:
               update_list[update_idx][week_list[i]] = nan            
           elif type(update_list[update_idx][week_list[i]]) == str:
               if re.match(pattern=r'((0?[0-9]|1[0-9])|2[0-3]):[0-5][0-9]', string=update_list[update_idx][week_list[i]]) != None:
                   update_item = re.match(pattern=r'((0?[0-9]|1[0-9])|2[0-3]):[0-5][0-9]', string=update_list[update_idx][week_list[i]]).group()
                   update_list[update_idx][week_list[i]] = DateTime().conv_datetime('1900-01-01 '+ update_item + ':00')
               else:
                   update_list[update_idx][week_list[i]] = nan
           else:
               update_list[update_idx][week_list[i]] = nan
               
       return update_list

   def update_attendance_time(self, member_list:list, time_table_list:list):
       week_list:list = [5, 9, 13, 17, 21]
       time_table_attendance_list:list = []
       member_attendance_time_list:list = []

       # error case
       if (len(time_table_list) != len(member_list)):
           return

       # time table type change
       for j in range(len(time_table_list)):
           time_table_attendance = []
           for i in range(len(time_table_list[j].values)):
               time_table_attendance.append(DateTime().conv_datetime(date_str='1900-01-01 '+ time_table_list[j].values[i][0]+ ':00'))
           time_table_attendance_list.append(time_table_attendance)

       # stamping time extract datetime
       for j in range(len(member_list)):
           member_attendance_time = []
           for i in range(len(week_list)):
               member_attendance_time = DateTime().judge_datetime(member_list=member_attendance_time, datetime_str=member_list[j][week_list[i]])
           member_attendance_time_list.append(member_attendance_time)
       
       # update attendance time
       for j in range(len(member_list)):
           self.remove_ravel(update_list=member_list, update_idx=j, week_list=week_list)
           if self.member_type == MemberType.PARTNER:
               self.round_up_15_min(update_list=member_list, update_idx=j,week_list=week_list)
           for i in range(len(time_table_attendance_list[j])):
               if type(member_attendance_time_list[j][i]) == float:
                   continue
               # case stamping time <= table time
               if member_attendance_time_list[j][i].time() <= time_table_attendance_list[j][i].time():
                   # round to time table hours
                   self.round_time(update_list=member_list, update_idx=j, time_table_list=time_table_attendance_list[j],time_table_idx=i, week_list=week_list)

       return member_list

   def update_leaving_work(self, member_list:list, time_table_list:list):
       week_list:list = [8, 12, 16, 20, 24]
       time_table_leaving_work_list:list = []
       time_table_overtime_start_list:list = []
       member_leaving_work_time_list:list = []

       # error case
       if (len(time_table_list) != len(member_list)):
           return

       # time table type change
       for j in range(len(time_table_list)):
           time_table_leaving_work = []
           time_table_overtime_start = []
           for i in range(len(time_table_list[j].values)):
               time_table_leaving_work.append(DateTime().conv_datetime(date_str='1900-01-01 '+ time_table_list[j].values[i][1]+ ':00'))
               time_table_overtime_start.append(DateTime().conv_datetime(date_str='1900-01-01 '+ time_table_list[j].values[i][2]+ ':00'))
           time_table_leaving_work_list.append(time_table_leaving_work)
           time_table_overtime_start_list.append(time_table_overtime_start)

       # stamping time extract datetime
       for j in range(len(member_list)):
           member_leaving_work_time = []
           for i in range(len(week_list)):
               member_leaving_work_time = DateTime().judge_datetime(member_list=member_leaving_work_time, datetime_str=member_list[j][week_list[i]])
           member_leaving_work_time_list.append(member_leaving_work_time)
       
       # update leaving work time
       for j in range(len(member_list)):
           self.remove_ravel(update_list=member_list, update_idx=j, week_list=week_list)
           if self.member_type == MemberType.PARTNER:
               self.round_down_15_min(update_list=member_list, update_idx=j,week_list=week_list)
           for i in range(len(time_table_leaving_work_list[j])):
               #  irregular case
               if type(member_leaving_work_time_list[j][i]) == float:
                   continue
               # case stamping time >= table time
               elif  member_leaving_work_time_list[j][i].time() >= time_table_leaving_work_list[j][i].time():
                   # case stamping time < overtime start time
                   if member_leaving_work_time_list[j][i].time() < time_table_overtime_start_list[j][i].time():
                       # round to time table hours
                       self.round_time(update_list=member_list, update_idx=j, time_table_list=time_table_leaving_work_list[j],time_table_idx=i, week_list=week_list)

       return member_list

   def round_down_15_min(self, update_list:list, update_idx:int, week_list:list):
       INTERVAL_MINUTE:int = 15
       for i in range(len(week_list)):
           if type(update_list[update_idx][week_list[i]]) == datetime.datetime:
               if update_list[update_idx][week_list[i]].minute%15 == 0:
                   pass
               else:
                   tmp = update_list[update_idx][week_list[i]].replace(minute = update_list[update_idx][week_list[i]].minute - (update_list[update_idx][week_list[i]].minute % INTERVAL_MINUTE), second=0, microsecond=0) 
                   update_list[update_idx][week_list[i]] = tmp

       return update_list

   def round_up_15_min(self, update_list:list, update_idx:int, week_list:list):
       INTERVAL_MINUTE:int = 15
       for i in range(len(week_list)):
           if type(update_list[update_idx][week_list[i]]) == datetime.datetime:
               if update_list[update_idx][week_list[i]].minute%15 == 0:
                   pass
               elif ((update_list[update_idx][week_list[i]].minute // INTERVAL_MINUTE) +1)*INTERVAL_MINUTE == 60:
                   tmp = update_list[update_idx][week_list[i]].replace(hour = update_list[update_idx][week_list[i]].hour+1 ,minute = (((update_list[update_idx][week_list[i]].minute // INTERVAL_MINUTE) +1)*INTERVAL_MINUTE)%60, second=0, microsecond=0) 
                   update_list[update_idx][week_list[i]] = tmp
               else:
                   tmp = update_list[update_idx][week_list[i]].replace(minute = (((update_list[update_idx][week_list[i]].minute // INTERVAL_MINUTE) +1)*INTERVAL_MINUTE), second=0, microsecond=0) 
                   update_list[update_idx][week_list[i]] = tmp

       return update_list

class DateTime:
   def __init__(self):
       pass

   def conv_datetime(self, date_str:str):
       return datetime.datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')

   def judge_datetime(self, member_list:list, datetime_str:str):
       if type(datetime_str) == datetime.datetime:
           member_list.append(datetime_str)

       elif type(datetime_str) == float:
           member_list.append(nan)

       else:
           if re.match(pattern=r'((0?[0-9]|1[0-9])|2[0-3]):[0-5][0-9]', string=datetime_str) != None:
               member_item = re.match(pattern=r'((0?[0-9]|1[0-9])|2[0-3]):[0-5][0-9]', string=datetime_str).group()
               member_list.append(self.conv_datetime('1900-01-01 '+ member_item + ':00'))
           else:
               member_list.append(nan)

       return member_list

class CsvController:
   def __init__(self, csv_path:str):
       self.csv_path = csv_path

   # read csv
   def read_csv(self):
       root = os.path.dirname(os.path.abspath(sys.argv[0]))
       return pd.read_csv(os.path.join(root, self.csv_path), header=0, index_col=0)

class ExcelController:
   def __init__(self, elsx_path:str):
       self.elsx_path = elsx_path

   # read elsx
   def read_elsx(self):
       root = os.path.dirname(os.path.abspath(sys.argv[0]))
       return pd.read_excel(os.path.join(root, self.elsx_path), sheet_name=None, header=0)

   # write elsx
   def write_elsx(self, data_list:list, sheet_name:str):
       root = os.path.dirname(os.path.abspath(sys.argv[0]))
       df = pd.DataFrame(data_list)
       return df.to_excel(os.path.join(root, self.elsx_path),sheet_name=sheet_name, index=False, header=2)

class ConfigController:
   def __init__(self, config_file_path:str):
       self.config_file_path = config_file_path

   def read_config(self):
       root = os.path.dirname(os.path.abspath(sys.argv[0]))
       config = configparser.ConfigParser()
       # join root directory
       config.read(os.path.join(root, self.config_file_path), encoding='utf-8')
       return config

   def extract_weekly_clocking_path(self, config):
       clocking_path = config.get('SETTING', 'WeeklyClockingPath')
       return clocking_path

   def extract_target_list_path(self, config):
       list_path = config.get('SETTING', 'TargetListPath')
       return list_path

   def extract_target_sheet(self, config):
       target_sheet = config.get('DEFAULT', 'TargetListSheetNane')
       return target_sheet

   def extract_weekly_proper_sheet(self, config):
       proper_sheet = config.get('DEFAULT', 'WeeklyClockingProperSheetNane')
       return proper_sheet

   def extract_weekly_partner_sheet(self, config):
       partner_sheet = config.get('DEFAULT', 'WeeklyClockingPartnerSheetNane')
       return partner_sheet

   def extract_output_proper_sheet(self, config):
       proper_sheet = config.get('DEFAULT', 'OutputProperSheetName')
       return proper_sheet

   def extract_output_partner_sheet(self, config):
       partner_sheet = config.get('DEFAULT', 'OutputPartnerSheetName')
       return partner_sheet

   def extract_output_proper_attendance_coloumn(self, config):
       attendance_coloumn = config.get('DEFAULT', 'OutputProperAttendanceColumn')
       return attendance_coloumn

   def extract_output_proper_leaving_coloumn(self, config):
       leaving_coloumn = config.get('DEFAULT', 'OutputProperLeavingColumn')
       return leaving_coloumn

   def extract_output_partner_attendance_coloumn(self, config):
       attendance_coloumn = config.get('DEFAULT', 'OutputPartnerAttendanceColumn')
       return attendance_coloumn

   def extract_output_partner_leaving_coloumn(self, config):
       leaving_coloumn = config.get('DEFAULT', 'OutputPartnerLeavingColumn')
       return leaving_coloumn

class DataFrameController:
   def __init__(self, sheetName:str):
       self.sheetName = sheetName

   def get_name(self, df):
       name_list = []
       target_list = df[self.sheetName]._values
       # get name roop
       for i in range(len(target_list)):
           name_list.append(target_list[i][0])
       return name_list

   def get_id(self, df):
       id_list = []
       target_list = df[self.sheetName]._values
       # get id roop
       for i in range(len(target_list)):
           id_list.append(target_list[i][1])
       return id_list

   def get_proper_id(self, df):
       id_list = []
       target_list = df[self.sheetName]._values
       # get id roop
       for i in range(len(target_list)):
           if ('S' in target_list[i][1]):
               id_list.append(target_list[i][1])
       return id_list

   def get_partner_id(self, df):
       id_list = []
       target_list = df[self.sheetName]._values
       # get id roop
       for i in range(len(target_list)):
           if ('S' not in target_list[i][1]):
               id_list.append(target_list[i][1])
       return id_list

   def get_time_table(self, df, id_list):
       time_table_list= df[self.sheetName]._values
       extract_list = []
       
       # get time table roop
       for j in range(len(id_list)):
           for i in range(len(time_table_list)):
               result = id_list[j] in time_table_list[i]
               if result == True:
                   extract_list.append(time_table_list[i][2])
       return extract_list

   def get_proper_current_elsx(self, df):
       elsx_list = []
       target_list = df[self.sheetName]._values
       # get elsx list roop
       for i in range(len(target_list)):
           if ('S' in target_list[i][1]):
               elsx_list.append(target_list[i][3])
       return elsx_list

   def get_proper_next_elsx(self, df):
       elsx_list = []
       target_list = df[self.sheetName]._values
       # get elsx list roop
       for i in range(len(target_list)):
           if ('S' in target_list[i][1]):
               elsx_list.append(target_list[i][4])
       return elsx_list

   def get_partner_current_elsx(self, df):
       elsx_list = []
       target_list = df[self.sheetName]._values
       # get elsx list roop
       for i in range(len(target_list)):
           if ('S' not in target_list[i][1]):
               elsx_list.append(target_list[i][3])
       return elsx_list

   def get_partner_next_elsx(self, df):
       elsx_list = []
       target_list = df[self.sheetName]._values
       # get elsx list roop
       for i in range(len(target_list)):
           if ('S' not in target_list[i][1]):
               elsx_list.append(target_list[i][4])
       return elsx_list

   def extract_weekly_clocking(self, df, id_list:list):
       weekly_clocking_list = df[self.sheetName]._values
       extract_list = []
       # extract list with id
       for i in range(len(id_list)):
           for j in range(len(weekly_clocking_list)):
               result = id_list[i] in weekly_clocking_list[j]
               if result == True:
                   extract_list.append(weekly_clocking_list[j])
       return extract_list
   
   def get_period(self, df):
       weekly_clocking_list = df[self.sheetName].columns
       period_list = []
       # get period roop
       for i in range(len(weekly_clocking_list)):
           if re.match(pattern=r'([1-9]|[12][0-9]|3[01])日', string=weekly_clocking_list[i]) != None:
               period_item = re.sub(pattern = r"\D", repl="", string=weekly_clocking_list[i])
               period_list.append(period_item)
       return period_list

   def update_data_frame(self, sheet_name:str, attendance_column:int, leaving_column:int, period_list:list, member_list, current_month_df, next_month_df):
       attendance_week_list = [5, 9, 13, 17, 21]
       leaving_week_list = [8, 12, 16, 20, 24]
       current_month_list:list = []
       next_month_list:list = []
       all_current_month_list:list = []
       all_next_month_list:list = []
       next_month_flag:bool = False
       start_period:int = 0

       # error case
       if (len(current_month_df) != len(member_list)):
           return

       for k in range(len(period_list)):
           if len(period_list) == k+1:
               break
           if period_list[k] > period_list[k+1]:
               next_month_flag = True
               start_period = period_list[k+1]
               break

       for j in range(len(current_month_df)):
           current_row = []
           current_month_list = []
           for i in range(len(current_month_df[j][sheet_name])):
               current_row = current_month_df[j][sheet_name].values[i]
               # match period
               if float(current_month_df[j][sheet_name].values[i][0]) == float(period_list[0]):
                   current_row[int(attendance_column)] = member_list[j][attendance_week_list[0]]
                   current_row[int(leaving_column)] = member_list[j][leaving_week_list[0]]
               elif float(current_month_df[j][sheet_name].values[i][0]) == float(period_list[1]) and float(period_list[1]) < float(start_period):
                   current_row[int(attendance_column)] = member_list[j][attendance_week_list[1]]
                   current_row[int(leaving_column)] = member_list[j][leaving_week_list[1]]
               elif float(current_month_df[j][sheet_name].values[i][0]) == float(period_list[2]) and float(period_list[2]) < float(start_period):
                   current_row[int(attendance_column)] = member_list[j][attendance_week_list[2]]
                   current_row[int(leaving_column)] = member_list[j][leaving_week_list[2]]
               elif float(current_month_df[j][sheet_name].values[i][0]) == float(period_list[3]) and float(period_list[3]) < float(start_period):
                   current_row[int(attendance_column)] = member_list[j][attendance_week_list[3]]
                   current_row[int(leaving_column)] = member_list[j][leaving_week_list[3]]
               elif float(current_month_df[j][sheet_name].values[i][0]) == float(period_list[4]) and float(period_list[4]) < float(start_period):
                   current_row[int(attendance_column)] = member_list[j][attendance_week_list[4]]
                   current_row[int(leaving_column)] = member_list[j][leaving_week_list[4]]
               else:
                   pass
               
               current_month_list.append(current_row)
           all_current_month_list.append(current_month_list)

       for j in range(len(next_month_df)):
           next_row = []
           next_month_list = []
           for i in range(len(next_month_df[j][sheet_name])):
               next_row = next_month_df[j][sheet_name].values[i]
               # match period
               if True == next_month_flag:
                   if float(next_month_df[j][sheet_name].values[i][0]) == float(period_list[1]) and float(period_list[1]) >= float(start_period):
                       next_row[int(attendance_column)] = member_list[j][attendance_week_list[1]]
                       next_row[int(leaving_column)] = member_list[j][leaving_week_list[1]]
                   elif float(next_month_df[j][sheet_name].values[i][0]) == float(period_list[2]) and float(period_list[2]) >= float(start_period):
                       next_row[int(attendance_column)] = member_list[j][attendance_week_list[2]]
                       next_row[int(leaving_column)] = member_list[j][leaving_week_list[2]]
                   elif float(next_month_df[j][sheet_name].values[i][0]) == float(period_list[3]) and float(period_list[3]) >= float(start_period):
                       next_row[int(attendance_column)] = member_list[j][attendance_week_list[3]]
                       next_row[int(leaving_column)] = member_list[j][leaving_week_list[3]]
                   elif float(next_month_df[j][sheet_name].values[i][0]) == float(period_list[4]) and float(period_list[4]) >= float(start_period):
                       next_row[int(attendance_column)] = member_list[j][attendance_week_list[4]]
                       next_row[int(leaving_column)] = member_list[j][leaving_week_list[4]]
                   else:
                       pass
               
               next_month_list.append(next_row)
           all_next_month_list.append(next_month_list)

       return all_current_month_list, all_next_month_list


def main():
   proper_current_excel_df:list = []
   proper_next_excel_df:list = []
   partner_current_excel_df:list = []
   partner_next_excel_df:list = []

   ## ConfigController class field
   config_controller = ConfigController(config_file_path="config.ini")
   config = config_controller.read_config()

   # config item parameter
   clocking_path = config_controller.extract_weekly_clocking_path(config=config)
   list_path = config_controller.extract_target_list_path(config=config)
   target_sheet_name = config_controller.extract_target_sheet(config=config)
   weekly_proper_sheet_name = config_controller.extract_weekly_proper_sheet(config=config)
   weekly_partner_sheet_name = config_controller.extract_weekly_partner_sheet(config=config)
   output_proper_sheet_name = config_controller.extract_output_proper_sheet(config=config)
   output_proper_attendance_column = config_controller.extract_output_proper_attendance_coloumn(config=config)
   output_proper_leaving_column = config_controller.extract_output_proper_leaving_coloumn(config=config)
   output_partner_sheet_name = config_controller.extract_output_partner_sheet(config=config)
   output_partner_attendance_column = config_controller.extract_output_partner_attendance_coloumn(config=config)
   output_partner_leaving_column = config_controller.extract_output_partner_leaving_coloumn(config=config)

   ## ExcelController class field
   weekly_clocking_df = ExcelController(elsx_path=clocking_path).read_elsx()
   target_list_df = ExcelController(elsx_path=list_path).read_elsx()

   ## DataFrameController class field
   id_list = DataFrameController(sheetName=target_sheet_name).get_id(df=target_list_df)
   proper_id_list = DataFrameController(sheetName=target_sheet_name).get_proper_id(df=target_list_df)
   partner_id_list = DataFrameController(sheetName=target_sheet_name).get_partner_id(df=target_list_df)
   proper_time_table_list = DataFrameController(sheetName=target_sheet_name).get_time_table(df=target_list_df, id_list=proper_id_list)
   partner_time_table_list = DataFrameController(sheetName=target_sheet_name).get_time_table(df=target_list_df, id_list=partner_id_list)
   proper_current_elsx_list = DataFrameController(sheetName=target_sheet_name).get_proper_current_elsx(df=target_list_df)
   proper_next_elsx_list = DataFrameController(sheetName=target_sheet_name).get_proper_next_elsx(df=target_list_df)
   partner_current_elsx_list = DataFrameController(sheetName=target_sheet_name).get_partner_current_elsx(df=target_list_df)
   partner_next_elsx_list = DataFrameController(sheetName=target_sheet_name).get_partner_next_elsx(df=target_list_df)
   weekly_proper_list = DataFrameController(sheetName=weekly_proper_sheet_name).extract_weekly_clocking(df=weekly_clocking_df, id_list=id_list)
   weekly_partner_list = DataFrameController(sheetName=weekly_partner_sheet_name).extract_weekly_clocking(df=weekly_clocking_df, id_list=id_list)
   proper_period = DataFrameController(sheetName=weekly_proper_sheet_name).get_period(df=weekly_clocking_df)
   partner_period = DataFrameController(sheetName=weekly_partner_sheet_name).get_period(df=weekly_clocking_df)

   ## ExcelController class field
   for i in range(len(proper_current_elsx_list)):
       proper_current_excel_df.append(ExcelController(elsx_path=proper_current_elsx_list[i]).read_elsx())
       proper_next_excel_df.append(ExcelController(elsx_path=proper_next_elsx_list[i]).read_elsx())

   for i in range(len(partner_current_elsx_list)):
       partner_current_excel_df.append(ExcelController(elsx_path=partner_current_elsx_list[i]).read_elsx())
       partner_next_excel_df.append(ExcelController(elsx_path=partner_next_elsx_list[i]).read_elsx())

   ## CsvController class field
   proper_time_table:list = []
   for i in range(len(proper_time_table_list)):
       proper_time_table.append(CsvController(csv_path=proper_time_table_list[i]).read_csv())

   partner_time_table:list = []
   for i in range(len(partner_time_table_list)):
       partner_time_table.append(CsvController(csv_path=partner_time_table_list[i]).read_csv())
   
   ## Member class field
   proper_controller = Member(member_type=MemberType.PROPER)
   proper_controller.update_attendance_time(member_list=weekly_proper_list, time_table_list=proper_time_table)
   proper_controller.update_leaving_work(member_list=weekly_proper_list, time_table_list=proper_time_table)

   partner_controller = Member(member_type=MemberType.PARTNER)
   partner_controller.update_attendance_time(member_list=weekly_partner_list, time_table_list=partner_time_table)
   partner_controller.update_leaving_work(member_list=weekly_partner_list, time_table_list=partner_time_table)

   current_proper_list, next_proper_list = DataFrameController(sheetName='').update_data_frame(sheet_name=output_proper_sheet_name, attendance_column=output_proper_attendance_column, leaving_column=output_proper_leaving_column, period_list=proper_period, member_list=weekly_proper_list, current_month_df=proper_current_excel_df, next_month_df=proper_next_excel_df)
   current_partner_list, next_partner_list = DataFrameController(sheetName='').update_data_frame(sheet_name=output_partner_sheet_name, attendance_column=output_partner_attendance_column, leaving_column=output_partner_leaving_column, period_list=partner_period, member_list=weekly_partner_list, current_month_df=partner_current_excel_df, next_month_df=partner_next_excel_df)
   
   ## ExcelController class field
   for i in range(len(proper_current_elsx_list)):
       ExcelController(elsx_path=proper_current_elsx_list[i]).write_elsx(data_list=current_proper_list[i], sheet_name=output_proper_sheet_name)
       ExcelController(elsx_path=proper_next_elsx_list[i]).write_elsx(data_list=next_proper_list[i], sheet_name=output_proper_sheet_name)
       
   for i in range(len(partner_current_elsx_list)):
       ExcelController(elsx_path=partner_current_elsx_list[i]).write_elsx(data_list=current_partner_list[i], sheet_name=output_partner_sheet_name)
       ExcelController(elsx_path=partner_next_elsx_list[i]).write_elsx(data_list=next_partner_list[i], sheet_name=output_partner_sheet_name)

main()

config.ini

[SETTING]
WeeklyClockingPath = input\一週間の打刻状況.xlsx
TargetListPath = input\対象者リスト.xlsx

[DEFAULT]
WeeklyClockingPartnerSheetNane = パートナー
WeeklyClockingProperSheetNane = プロパ
TargetListSheetNane = シート1
OutputProperSheetName = シート1
OutputProperAttendanceColumn = 2
OutputProperLeavingColumn = 3
OutputPartnerSheetName = シート1
OutputPartnerAttendanceColumn = 2
OutputPartnerLeavingColumn = 3

input配下

まだまだ作りかけですねー。
config周りは参考になるかと思います。

いいなと思ったら応援しよう!