excel raise与offset

本文详细介绍了Excel中Range对象的Resize和Offset属性使用方法。包括单个及多个单元格的平移、整行整列的操作技巧,以及如何调整单元格区域的大小。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Resize和Offset属性介绍


首先声明,这里讨论的Resize属性和Offset属性都是属于Range对象的,通过以下格式进行引用:
Range.Offset(RowOffset, ColumnOffset)
Range.Resize(RowSize, ColumnSize)

Range.Offset(RowOffset, ColumnOffset)
单元格区域.偏移(行偏移量,列偏移量)
大概解释一下:指定的单元格区域,根据行偏移量和列偏移量进行整体平移,得到同样大小的单元格区域,但是地址可能发生了变化;
行偏移量,列偏移量的取值范围:负整数、零、正整数
行偏移量,列偏移量的默认值:零

Range.Resize(RowSize, ColumnSize)
单元格区域.重新确定区域(行数,列数)
大概解释一下:以指定单元格区域的左上角单元格为起点,根据行数和列数向右下方进行扩展,得到一个新的单元格区域,区域大小和地址都可能发生了变化。
行数、列数的取值范围:正整数
行数列数的默认值:指定单元格区域的当前行数、指定单元格区域的当前列数。(这个概念很重要)



二、Offset属性使用示例



Offset使用示例1:单个单元格情况
(1)行偏移量正整数:向下移;列偏移量正整数:向右移。
Range(“B2”).offset(1,1)
单元格向下移1行,向右移1列,得到单元格C3
(2)行偏移量负整数:向上移;列偏移量负整数:向左移。
Range(“B2”).offset(-1,-1)
单元格向上移1行,向左移1列,得到单元格A1
(3)行偏移量、列偏移量为零:原地踏步
Range(“B2”).offset(0,0)
单元格行列均不变化,得到单元格B2
Range(“B2”).offset(0,1)
单元格行无偏移、向右移1列,得到单元格C2
Range(“B2”).offset(1,0)
单元格向下移1行,列无偏移,得到单元B3
(4)行偏移量,列偏移量省略:默认零值
下面这几种情况是结果是一样的
行偏移量、列偏移量参数都省略:Range(“B2”).offset()
列偏移量参数省略:Range(“B2”).offset(0)
行偏移量参数省略:Range(“B2”).offset(,0)
这三种情况和Range(“B2”).offset(0,0)的结果是一样的,都是单元格行列均不变化,得到单元格B2。


Offset使用示例2:多个单元格情况
(1)Range("B2:C3").Offset(1, 1)
单元格”B2:C3”区域整体向下移1行,向右移1列,得到单元格区域”C3:D4”
(2)Range("B2:C3").Offset(-1, -1)
单元格”B2:C3”区域整体向上移1行,向左移1列,得到单元格区域”A1:B2”
(3)Range("B2:C3").Offset(0, 0)
单元格”B2:C3”区域整体原地踏步,得到单元格区域”B2:C3”
(4)Range("B2:C3").Offset(1, 0)
单元格”B2:C3”区域整体向下移1行,列无偏移,得到单元格区域”B3:C4”
(5)Range("B2:C3").Offset(0, 1)
单元格”B2:C3”区域整体行无偏移,向左移1列,得到单元格区域”C2:D3”
(6)以下省略参数情况等价与Range("B2:C3").Offset(0, 0)
Range("B2:C3").Offset(),Range("B2:C3").Offset(, 0), Range("B2:C3").Offset(0)


Offset使用示例3:整列情况
(1)Range("B2").EntireColumn.Offset(0, 1)
单元格区域”B列”整体右移1列,得到单元格”C列”
(2)Range("B2").EntireColumn.Offset(0, -1)
单元格区域”B列”整体右移1列,得到单元格”A列”
(3)以上两个例子可以采用省略写法
Range("B2").EntireColumn.Offset(, -1)
(4)注意下面这写法是错误的
Range("B2").EntireColumn.Offset(1, 1)
Range("B2").EntireColumn.Offset(-1, 1)
当单元格区域是整列时,行偏移量只能是0,或者省略,不能是正整数或负整数,切记


Offset使用示例4:整行情况
整行行情况与整列情况相似,我仅给出正确写法与错误写法,详细代码可以看附件
正确写法:
Range("B2").EntireRow.Offset(1, 0)
Range("B2").EntireRow.Offset(-1, 0)
Range("B2").EntireRow.Offset(1)
错误写法:
Range("B2").EntireRow.Offset(1, 1)
Range("B2").EntireRow.Offset(-1, 1)
当单元格区域是整行时,列偏移量只能是0,或者省略,不能是正整数或负整数,切记

三、Resize属性使用示例


Resize使用示例
(1)但单元格和多单元格使用Resize属性
一般情况下,Resize属性不存在单单元格与多单元格的区别,无论区域大小,总是以单元格区域的左上角单元格为起点,根据行数和列数向右下方进行扩展,得到一个新的单元格区域;
Range("A1").Resize(1, 1)
Range("A1:B2").Resize(1, 1)
这两条语句效果是一样的,都以从”A1”单元格为开始(包含A1单元格),扩展1行,扩展1列,结果得到单元格区域都是A1


Range("A1").Resize(2, 2)
Range("A1:B2").Resize(2,2)
同样,这两条语句效果也是一样的,从”A1”单元格为开始(包含A1单元格),扩展2行,扩展2列,结果得到单元格区域都是A1:B2


(2)Resize参数省略的情况
当Resize内容参数省略的时候,单单元格与多单元格就出现了区别,当参数省略的时候,行数为当前单元格区域行数,列数为当前单元格区域列数,我个人感觉这个非常灵活,所以我经常出错;


Range("A1").Resize()
在上面这个语句中,单元格区域是A1,行数是1,列数是1,因为参数进行了省略,采用了默认值,那就是从”A1”单元格为开始(包含A1单元格),扩展1行,扩展1列,结果得到单元格区域是A1
其实把上面这条语句写完全,就是这样的Range("A1").Resize(1,1)


Range("A1:B2").Resize()
我们继续来分析这条语句,单元格区域是"A1:B2",是由两行两列组成的单元格,那么行数是2,列数是2,因为参数进行了省略,采用了默认值,那就是从”A1”单元格为开始(包含A1单元格),扩展2行,扩展2列,结果得到单元格区域是"A1:B2";
把这条语句写全,应该是Range("A1:B2").Resize(2,2)

(3)整列的情况
Range("A1").EntireColumn.Resize(, 3)
我们来分析上面的语句,单元格区域是”A列”,行数省略,代表了所有行,列数是3,那就是从”A1”单元格为开始(包含A1单元格),扩展所有行,扩展3列,结果得到单元格区域是"A:C";
注意,整列情况不能写行数,否则就无法扩展整列啦,切记;


(4)整行的情况
Range("A1").EntireRow.Resize(3)
我们来分析上面的语句,单元格区域是”第1行”,行数是3,列数省略,代表了所有列,就是从”A1”单元格为开始(包含A1单元格),扩展3行,扩展所有列,结果得到单元格区域是"1:3";
注意,整列情况不能写行数,否则就无法扩展整列啦,切记;


(5)错误的写法
Range("A1").Resize(0, 1)
Range("A1").Resize(-1, 1)
行数和列数都不能出项零值和负值,以上语句必然报错

import pandas as pd import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import interp1d from scipy.optimize import curve_fit, root_scalar import os # 使用原始字符串避免Windows路径问题 excel_path = r'D:\PYC\PythonProject\est.xlsx' def calculate_youngs_modulus(excel_path, strain_col='真实应变', stress_col='真实应力', offset=0.002, youngs_modulus_override=None): """ 从Excel数据拟合杨氏模量并计算交点 参数: excel_path: Excel文件路径 strain_col: 应变数据列名 (默认 '真实应变') stress_col: 应力数据列名 (默认 '真实应力') offset: 屈服强度延伸率(例如0.002代表0.2%) 返回: youngs_modulus: 杨氏模量值 (MPa) yield_point: 交点坐标 (应变, 应力) fracture_elongation: 断裂延伸率 tensile_strength: 抗拉强度 intersection_points: 曲线平移直线的交点列表 [(应变, 应力)] """ try: # 1. 读取Excel数据 df = pd.read_excel(excel_path) # 检查必要列 if '真实应变' not in df.columns or '真实应力' not in df.columns: print("错误: Excel文件中缺少必要的列") return None, None, None, None, None # 数据预处理 strain = df['真实应变'].values.astype(float) stress = df['真实应力'].values.astype(float) # 确保应变按升序排列 sort_idx = np.argsort(strain) strain = strain[sort_idx] stress = stress[sort_idx] # 强制添加原点 (0,0) 如果不存在 if strain[0] > 0 or stress[0] > 0: strain = np.insert(strain, 0, 0.0) stress = np.insert(stress, 0, 0.0) # 创建插值函数表示原始曲线 curve_func = interp1d(strain, stress, kind='linear', fill_value="extrapolate") # 核心函数:计算斜率(杨氏模量),强制通过原点 def calculate_slope(elastic_strain, elastic_stress, slope_override=None): """ 计算直线斜率(杨氏模量),强制通过原点 如果提供slope_override,则使用该值作为斜率 """ if slope_override is not None: return slope_override # 使用最小二乘法计算斜率:y = mx → m = Σ(x*y)/Σ(x²) numerator = np.sum(elastic_strain * elastic_stress) denominator = np.sum(elastic_strain ** 2) if denominator < 1e-10: # 尝试使用前两个点直接计算斜率 if len(elastic_strain) >= 2: return (elastic_stress[1] - elastic_stress[0]) / (elastic_strain[1] - elastic_strain[0]) return None return numerator / denominator # 识别弹性阶段数据点(基于自动拟合) def identify_elastic_region(): """自动识别弹性阶段数据点""" best_r2 = -np.inf best_idx = 2 # 至少包含原点和第一个点 # 确定最大尝试点数(避免处理过多点) max_points = min(50, len(strain)) # 从第3个点开始(跳过原点) for i in range(3, max_points): x = strain[:i] y = stress[:i] # 计算斜率(强制过原点) slope = np.sum(x * y) / np.sum(x ** 2) # 跳过无效斜率 if slope <= 0 or np.isnan(slope): continue y_pred = slope * x # 计算R² ss_res = np.sum((y - y_pred) ** 2) ss_tot = np.sum((y - np.mean(y)) ** 2) r2 = 1 - (ss_res / ss_tot) if ss_tot > 1e-10 else 0 # 更新最佳拟合 if r2 > best_r2: best_r2 = r2 best_idx = i return strain[:best_idx], stress[:best_idx], best_idx # 主逻辑 if youngs_modulus_override is None: # 自动模式:识别弹性阶段并拟合 elastic_strain, elastic_stress, best_idx = identify_elastic_region() youngs_modulus = calculate_slope(elastic_strain, elastic_stress) else: # 覆盖模式:使用用户指定的斜率 youngs_modulus = youngs_modulus_override # 确保杨氏模量有效 if youngs_modulus is None or np.isnan(youngs_modulus) or youngs_modulus <= 0: # 使用备用方法计算杨氏模量:取前5个点的平均斜率 if len(strain) >= 5: slopes = [] for i in range(1, 5): slope = (stress[i] - stress[0]) / (strain[i] - strain[0]) if slope > 0: slopes.append(slope) if slopes: youngs_modulus = np.mean(slopes) print(f"警告: 使用备用方法计算杨氏模量: {youngs_modulus:.2f} MPa") else: raise ValueError("杨氏模量计算失败: 无法找到有效的斜率") else: raise ValueError("杨氏模量计算失败: 数据点不足") # 构造平移直线: y = E*(x - offset) offset_line = lambda x: youngs_modulus * (x - offset) # 计算交点 intersection_points = [] def intersection_eq(x): return curve_func(x) - offset_line(x) # 在应变范围内搜索交点 search_range = np.linspace(offset, max(strain), 1000) diffs = intersection_eq(search_range) sign_changes = np.where(np.diff(np.sign(diffs)))[0] for i in sign_changes: if i < len(search_range) - 1: try: sol = root_scalar(intersection_eq, bracket=(search_range[i], search_range[i + 1]), method='brentq') if sol.converged: x_int = sol.root y_int = offset_line(x_int) if min(strain) <= x_int <= max(strain): intersection_points.append((x_int, y_int)) except: continue # 去重处理 unique_points = [] tolerance = 1e-5 for point in intersection_points: if not any(abs(point[0] - p[0]) < tolerance for p in unique_points): unique_points.append(point) # 按应变值排序交点 unique_points.sort(key=lambda x: x[0]) # 计算其他力学性能 max_stress_idx = np.argmax(stress) tensile_strength = stress[max_stress_idx] fracture_elongation = strain[max_stress_idx] # 断裂延伸率应为最后一个数据点的应变 # 屈服点取第一个交点 yield_point = unique_points[0] if unique_points else (np.nan, np.nan) # 8. 可视化结果 plt.figure(figsize=(10, 6)) plt.plot(strain, stress, 'bo-', label='原始数据', alpha=0.7) # 计算y轴上限 (原始数据应力最大值的1.1倍) y_max = max(stress) * 1.1 # 绘制平移直线 offset_fit_x = np.linspace(offset, max(strain), 50) offset_fit_y = offset_line(offset_fit_x) plt.plot(offset_fit_x, offset_fit_y, 'g--', linewidth=2, label=f'偏移{offset * 100:.1f}%直线') # 标记交点 if unique_points: for i, (x, y) in enumerate(unique_points): plt.plot(x, y, 'r*', markersize=10, label=f'交点{i + 1} (ε={x:.4f}, σ={y:.1f} MPa)') # 设置y轴范围 plt.ylim(0, y_max) plt.title('材料应力-应变曲线交点分析', fontsize=14) plt.xlabel('应变 (ε)', fontsize=12) plt.ylabel('应力 (σ, MPa)', fontsize=12) plt.legend() plt.grid(True, linestyle='--', alpha=0.7) plt.tight_layout() # 保存图表 output_dir = os.path.dirname(excel_path) chart_path = os.path.join(output_dir, 'stress_strain_intersection.png') plt.savefig(chart_path, dpi=300) plt.close() # 关闭图表避免内存泄漏 print(f"\n图表已保存为 '{chart_path}'") return youngs_modulus, yield_point, fracture_elongation, tensile_strength, unique_points except Exception as e: print(f"分析过程中出错: {str(e)}") return None, None, None, None, None # 执行函数 if __name__ == "__main__": if not os.path.exists(excel_path): print(f"错误: 文件不存在 - {excel_path}") else: print(f"开始分析文件: {excel_path}") # 获取用户输入的偏移量 user_offset = input("请输入屈服强度延伸率(例如0.002代表0.2%),直接回车则使用默认值0.002: ") if user_offset.strip() == '': offset_val = 0.002 else: try: offset_val = float(user_offset) except ValueError: print("输入无效,将使用默认值0.002") offset_val = 0.002 # 获取用户输入的杨氏模量 user_youngs_modulus = input("请输入杨氏模量(单位:MPa),回车跳过将自动计算: ") if user_youngs_modulus.strip() == '': youngs_modulus_val = None else: try: youngs_modulus_val = float(user_youngs_modulus) except ValueError: print("输入无效,将自动计算杨氏模量") youngs_modulus_val = None # 调用函数并获取交点 results = calculate_youngs_modulus( excel_path, offset=offset_val, youngs_modulus_override=youngs_modulus_val) E, yield_point, fracture_elongation, tensile_strength, intersection_points = results if E is not None: print(f"\n最终结果: 杨氏模量 = {E:.2f} MPa") if not np.isnan(yield_point[0]): print(f"屈服点应力 = {yield_point[1]:.2f} MPa") print(f"真实抗拉强度 = {tensile_strength:.2f} MPa") print(f"真实断裂延伸率 = {fracture_elongation:.6f}") # 输出所有交点坐标 if intersection_points: print("\n所有交点坐标:") for i, (strain_val, stress_val) in enumerate(intersection_points, 1): print(f"交点{i}: 应变 = {strain_val:.6f}, 应力 = {stress_val:.2f} MPa") else: print("未找到交点") else: print("分析失败,请检查输入数据和错误信息") 修改该代码,我需要截距
最新发布
07-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值