我正在编写一个小脚本来填充电子表格中 2 个模块的时间值和功率值。 A 列和 C 列将存储模块 1 的时间和功率值,而 B 列和 D 列将存储模块 2 的时间和功率值。我在将值附加到第二个模块的初始行时遇到困难。任何帮助表示赞赏。下面是代码:
# get user inputs
try:
step_size = float(self.step_size_entry.get())
hold_time = float(self.hold_time_entry.get())
upper_bound = float(self.upper_bound_entry.get())
lower_bound = float(self.lower_bound_entry.get())
ramping = self.ramping_var.get()
selected_module = self.selected_module_var.get()
# create excel workbook and sheet
try:
wb = load_workbook("Test.xlsx")
if "data" in wb.sheetnames:
sheet = wb["data"]
else:
# add another sheet to the workbook
sheet = wb.create_sheet("data")
except FileNotFoundError:
wb = Workbook()
sheet = wb.active
sheet.title = "data"
# check if "data" sheet already exists
if "data" in wb.sheetnames:
sheet = wb["data"]
else:
# add another sheet to the workbook
sheet = wb.create_sheet("data")
# populate header row
sheet["A1"] = "Time 1"
sheet["B1"] = "Time 2"
sheet["C1"] = "Module 1"
sheet["D1"] = "Module 2"
# initialize variables
power = lower_bound
prev_power = None
# get the index of the last filled row for Module 1
last_row_m1 = len(sheet['A'])
last_row_m2 = len(sheet['B'])
# get the index of the last filled row for Module 2
# Calculate time_1 and time_2
if last_row_m1 > 1:
time_1 = (sheet.cell(row=last_row_m1, column=1).value) + (sheet.cell(row=last_row_m1, column=1).value - sheet.cell(row=last_row_m1- 1, column=1).value)
else:
time_1 = 1
if last_row_m2 > 1:
time_2_prev_value = sheet.cell(row=last_row_m2, column=2).value
if time_2_prev_value is None:
time_2_prev_value = 0
time_2 = time_2_prev_value + hold_time
else:
time_2 = 1
# if the sheet is empty, set last_row to 0
if last_row_m1 == 1 and sheet.cell(row=1, column=1).value is None:
last_row_m1 = 0
if last_row_m2 == 1 and sheet.cell(row=1, column=2).value is None:
last_row_m2 = 0
# populate power column based on ramping selection
if ramping == "Ascending" and selected_module == "Module 1":
while power <= upper_bound:
for i in range(int(hold_time)):
if power != prev_power: # Add row only if power value is changing
sheet.append([time_1, None, power, None])
prev_power = power
time_1 = time_1 + hold_time
power += step_size
if ramping == "Ascending" and selected_module == "Module 2":
while power <= upper_bound:
for i in range(int(hold_time)):
if power != prev_power: # Add row only if power value is changing
sheet.append([None, time_2, None, power])
prev_power = power
time_2 = time_2 + hold_time
power += step_size
# save and close workbook
wb.save("Test.xlsx")
wb.close()
#User Input 1:
#step_size = 10
#hold_time = 5
#upper_bound = 120
#lower_bound = 100
#ramping = "Ascending"
#selected_module = "Module 1"
#User Input 2:
#step_size = 10
#hold_time = 5
#upper_bound = 120
#lower_bound = 100
#ramping = "Ascending"
#selected_module = "Module 2"
时间1 | 时间2 | 电源1 | 电源2 |
---|---|---|---|
1 | 空白 | 100 | 空白 |
6 | 空白 | 110 | 空白 |
11 | 空白 | 120 | 空白 |
空白 | 1 | 空白 | 100 |
空白 | 6 | 空白 | 110 |
空白 | 11 | 空白 | 120 |
时间1 | 时间2 | 电源1 | 电源2 |
---|---|---|---|
5 | 5 | 100 | 100 |
10 | 10 | 110 | 110 |
15 | 15 | 120 | 120 |
空白 | 空白 | 空白 | 空白 |
空白 | 空白 | 空白 | 空白 |
空白 | 空白 | 空白 | 空白 |
感谢您的编辑,使展示示例变得更容易。
正如 @Redox 在他的评论中提到的,你的对齐问题是由于你使用了追加造成的。
如所示追加always添加到最后使用的行之后的下一个
例如如果最后使用的行是 10 并且我“工作表附加”一些数据,它将被放置在第 11 行。如果我执行另一个“工作表附加”,它将被放置在第 12 行和下一个附加、第 13 行等。
因此,为了添加“第二个”数据集(在添加第一个数据集之后),您不能使用“工作表附加”。您只能将值单独添加到所需的单元格。
另请注意
列的长度不返回指定列的最后使用的行。因此这些行;
last_row_m1 = len(sheet['A'])
和 last_row_m2 = len(sheet['B'])
sheet.max_row
。last_row_m1 = [x.row for x in sheet['A'] if x.value is not None][-1]
我对您的代码进行了一些修改,这将产生您想要的结果。它只是作为一个示例,因为它可能无法完全适应您的现实生活应用程序。
主要更改是允许通过附加或逐个单元格添加数据的方法,具体取决于数据是添加到新行还是插入到现有的已使用行中。
我还更改了添加要在同一块中完成的数据,因为使用的两个块基本上是代码重复。
为了进行测试,我在启用
### User Input 1:
数据和禁用 ### User Input 2:
数据且没有现有工作簿“Test.xlsx”的情况下运行了一次代码。然后在第一次运行中生成的工作簿上启用 ### User Input 2:
数据并禁用 ### User Input 1:
数据。time_2
将使用值 5 而不是 1 进行初始化,以区分模块 1 到模块 2 的数据集并复制提供的屏幕截图数据。
time_2 = 5 # Modified for debug testing
在此代码示例中,使用附加功能添加来自“### User Input 1:”的 A 列(“时间 1”)和 C(“模块 1”)中的数据,因为该数据是新行上的第一个数据。
“### 用户输入 2:”中的 B 列(“时间 2”)和 D(“模块 2”)中的数据是通过迭代每行列中的单元格并使用相同的列表数据来添加的。
from openpyxl import load_workbook, Workbook
### Enable each input data set one after the other
### User Input 1:
# step_size = 10
# hold_time = 5
# upper_bound = 120
# lower_bound = 100
# ramping = "Ascending"
# selected_module = "Module 1"
### User Input 2:
# step_size = 10
# hold_time = 5
# upper_bound = 120
# lower_bound = 100
# ramping = "Ascending"
# selected_module = "Module 2"
# create excel workbook and sheet
try:
wb = load_workbook("Test.xlsx")
if "data" in wb.sheetnames:
sheet = wb["data"]
else:
# add another sheet to the workbook
sheet = wb.create_sheet("data")
except FileNotFoundError:
wb = Workbook()
sheet = wb.active
sheet.title = "data"
# check if "data" sheet already exists
if "data" in wb.sheetnames:
sheet = wb["data"]
else:
# add another sheet to the workbook
sheet = wb.create_sheet("data")
# populate header row
sheet["A1"] = "Time 1"
sheet["B1"] = "Time 2"
sheet["C1"] = "Module 1"
sheet["D1"] = "Module 2"
# initialize variables
power = lower_bound
prev_power = None
# get the index of the last filled row for Module 1
# last_row_m1 = len(sheet['A'])
last_row_m1 = [x.row for x in sheet['A'] if x.value is not None][-1]
print(f"Last row m1 'last_row_m1: {last_row_m1}")
# last_row_m2 = len(sheet['B'])
last_row_m2 = [x.row for x in sheet['B'] if x.value is not None][-1]
print(f"Last row m2 'last_row_m2: {last_row_m2}")
sheet_last_row = sheet.max_row
print(f"Sheet last row 'sheet_last_row: {sheet_last_row}")
# get the index of the last filled row for Module 2
# Calculate time_1 and time_2
if last_row_m1 > 1:
time_1 = sheet.cell(row=last_row_m1, column=1).value + (
sheet.cell(row=last_row_m1, column=1).value - sheet.cell(row=last_row_m1 - 1, column=1).value)
else:
time_1 = 1
if last_row_m2 > 1:
time_2_prev_value = sheet.cell(row=last_row_m2, column=2).value
if time_2_prev_value is None:
time_2_prev_value = 0
time_2 = time_2_prev_value + hold_time
else:
time_2 = 5 # Modified for debug testing
# if the sheet is empty, set last_row to 0
if last_row_m1 == 1 and sheet.cell(row=1, column=1).value is None:
last_row_m1 = 0
if last_row_m2 == 1 and sheet.cell(row=1, column=2).value is None:
last_row_m2 = 0
# populate power column based on ramping selection
# if ramping == "Ascending" and selected_module == "Module 1":
### Determine if both column A and B are equal length.
### If Column B is shorter than Column A set the row to 2 (next after Header row)
### Otherwise start a next unused row
if last_row_m2 < last_row_m1:
row = 2
else:
row = sheet_last_row
### If input data is 'module 1' set time to time1 otherwise set to time_2
time = time_1 if selected_module == "Module 1" else time_2
add_list = []
while power <= upper_bound:
for i in range(int(hold_time)):
if power != prev_power: # Add row only if power value is changing
### Update the list of data to add depending on if we have 'Module 1' or 'Module 2'
add_list = [time, None, power, None] if selected_module == "Module 1" else [None, time, None, power]
### If there is no data already entered in the block i.e. first insert the
### data can be added using append
if sheet_last_row == 1:
sheet.append(add_list)
### If data has already been entered in the sheet then must add data cell by cell
else:
### Iterate the columns and enter the data from the list cell by cell
for x in range(len(add_list)):
new_value = add_list[x]
if new_value is not None:
sheet.cell(row=row, column=x+1).value = new_value
prev_power = power
row += 1
time = time + hold_time # Change time to be generic
power += step_size
wb.save("Test.xlsx")
wb.close()