propertysheet 创建失败

 今天弄propertysheet的建立,比较痛苦的搞了2个多小时

 

现象,无论模态还是非模态对话框,都会创建失败,m_hWnd返回-1,而且,奇怪的是,GetLastError()却返回0。自相矛盾的结果,不过总之还是失败了。

 

最终排查出原因如下,

可能也许有人也有这个习惯,将propertypage最为成员变量加入sheet中,并在创建sheet时自动初始化。这样可以封装的比较清晰,但问题是,切忌,addpage无论如何不能在sheet中OnCreat中调用,否则就会导致sheet建立失败,而放在在构造函数中是个不错的主意。

 

 

具体原因,如下:

不同于构造函数中,单纯的加入页面,在OnCreat中建立时,m_hWnd已经存在,这时候加入新的页,会试图做一些窗口操作,但是毕竟在OnCreat函数中,窗口还未真正的创建完毕,所以导致窗口操作的失败(SendMessage函数失败哦。。蛮罕见的),同时触发异常,将原来已经申请到的窗口句柄也损毁了,可能处理跳过了SetLastError()函数,所以GetLastError()也查不出来。

``` DATA: lv_sheet_name TYPE char20. * 1. 获取第一个工作表 DO 5 times. CALL METHOD OF application 'Worksheets' = source_sheet EXPORTING #1 = 1. " 索引1表示第一个工作表 * 2. 获取当前最后一个工作表作为锚点 GET PROPERTY OF application 'Worksheets' = sheets. " 获取工作表集合 GET PROPERTY OF sheets 'Count' = sheet_count. " 获取总表数 CALL METHOD OF sheets 'Item' = last_sheet EXPORTING #1 = sheet_count. " 按索引获取最后一个工作表 ** 3. 复制到最后一个工作表之后 CALL METHOD OF source_sheet 'Copy' EXPORTING #2 = last_sheet. " #2对应After参数(按位置传递) GET PROPERTY OF sheets 'Count' = sheet_count. " 重新获取总数 CALL METHOD OF sheets 'Item' = new_sheet. lv_sheet_name = |Sheet_{ sy-index }|. CALL METHOD OF new_sheet 'Name' = lv_sheet_name. PERFORM fill_excel_data USING new_sheet 11 4 0 'Test'. ENDDO. ENDFORM. *&---------------------------------------------------------------------* *& Form FILL_EXCEL_DATA *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * -->P_ENDFORM text *----------------------------------------------------------------------* FORM fill_excel_data USING iv_sheet type ole2_object i_row i_col bold p_value. * CALL METHOD OF workbook 'Worksheets' = iv_sheet * EXPORTING #1 = 'template'. " 默认名称 "CALL METHOD OF iv_sheet 'Name' = . CALL METHOD OF iv_sheet 'CELLS' = cell EXPORTING #1 = i_row #2 = i_col. IF sy-subrc <> 0. WRITE: / '获取单元格失败'. EXIT. ENDIF. * GET PROPERTY OF cell 'FONT' = font. * IF sy-subrc <> 0. * WRITE: / '获取字体属性失败'. * EXIT. * ENDIF. * SET PROPERTY OF font 'BOLD' = bold. SET PROPERTY OF cell 'VALUE' = p_value. IF sy-subrc <> 0. WRITE: / '设置单元格值失败'. EXIT. ENDIF. FREE OBJECT: cell, font. FREE OBJECT: new_sheet, last_sheet, source_sheet, sheets, workbook. ENDFORM.```这代码错在哪里,怎样才填充每个copy的sheet页?
最新发布
03-25
<think>好的,我现在需要分析用户提供的ABAP OLE操作Excel的代码,找出其中的错误,并解决如何正确填充每个复制的sheet页。让我仔细看看代码的结构和逻辑。 首先,用户的目标应该是通过循环复制第一个工作表多次,并在每个新工作表中填充数据。代码中使用了DO 5 TIMES循环,每次循环中复制工作表,然后调用FORM fill_excel_data来填充数据。但用户说填充每个复制的sheet页成功,所以需要找出哪里出了问题。 让我分步骤检查代码: 1. **获取第一个工作表**:在循环内部,使用CALL METHOD OF application 'Worksheets' = source_sheet,参数是#1=1。这里可能存在一个问题,因为每次循环都会重新获取第一个工作表,这可能没问题,但确定是否有必要在每次循环都这样做。过如果第一个工作表的位置变,可能会有问题。 2. **获取最后一个工作表作为锚点**:这里通过GET PROPERTY获取工作表集合和总数,然后调用Item方法获取最后一个工作表。这部分看起来正确,但要注意在复制后,工作表数量会增加,所以每次循环的sheet_count可能应该重新获取,但在当前代码中,这一步是在循环内部,所以每次循环开始时都会重新获取sheet_count,这样是正确的。 3. **复制到最后一个工作表之后**:调用source_sheet的Copy方法,参数#2=last_sheet。根据Excel的OLE方法,Worksheet.Copy方法的参数是Before和After,这里应该使用After参数,所以是否正确?可能需要确认参数的位置是否正确。在ABAP OLE中,参数是按位置传递的,所以#1对应第一个参数,可能是Before,而#2对应After。所以这里的#2=last_sheet应该是正确的,将源工作表复制到last_sheet之后。 4. **获取新创建的工作表**:复制之后,重新获取sheet_count,然后调用Item方法获取新工作表。这里可能存在一个问题,因为复制后的工作表总数是sheet_count+1,所以新工作表的索引应该是sheet_count+1,但代码中在复制之后再次GET sheet_count,这时候sheet_count已经增加了,对吗?例如,原来的sheet_count是N,复制之后变成N+1,所以Item的参数是新的sheet_count,即N+1,这时候获取的就是新创建的工作表。这应该是正确的。 5. **设置新工作表的名称**:尝试将新工作表命名为Sheet_{sy-index}。这里sy-index是DO循环的当前次数,从1到5。但Excel工作表名称有长度限制,能重复,且能包含特殊字符。如果原来的工作表名称中没有Sheet_1到Sheet_5的冲突,这应该没问题。否则会出错,但用户的问题可能在这里。 6. **调用FORM fill_excel_data**:传递new_sheet,以及行、列、加粗和值。问题可能出在这个子程序中。 接下来检查FORM fill_excel_data的实现: - 参数部分:iv_sheet类型为ole2_object,i_row=11,i_col=4,bold=0,p_value='Test'。目的是在单元格11行4列(即D11)写入'Test'。 - 在子程序中,使用CALL METHOD OF iv_sheet 'CELLS' = cell,参数i_row和i_col。这里是否正确获取了单元格?可能的问题:是否应该使用Workbook或Worksheet的Cells属性?或者是否调用方式错误? - 在代码中,原来的注释部分有关于获取Worksheets的代码被注释掉了,可能用户在这里有错误尝试。例如,是否有必要先激活或选择该工作表? - 设置单元格值的部分:SET PROPERTY OF cell 'VALUE' = p_value. 这里是否正确?如果单元格对象正确获取,应该可以设置。但可能的问题在于,是否单元格对象获取失败,导致设置值成功。 现在可能的问题点: 1. **在FORM fill_excel_data中没有正确获取单元格**:可能需要使用正确的方法来访问单元格。例如,是否应该使用iv_sheet的Cells方法,传入行和列?例如,在VBA中是Worksheets("Sheet1").Cells(row, col),而通过OLE可能需要正确的方法调用。 2. **对象释放问题**:在FORM fill_excel_data结束时,FREE OBJECT了cell, font等,但同时也FREE了new_sheet, last_sheet等,这些对象是在主程序中定义的,可能在子程序中释放会导致主程序中的引用失效?例如,在子程序中使用了FREE OBJECT new_sheet,而new_sheet是在主循环中创建的,每次循环迭代中都会被重新赋值,但在子程序中释放了,这可能导致后续使用的问题。 特别是,每次循环中,调用FORM后,执行了FREE OBJECT new_sheet,这会导致后续对该工作表的引用无效。因为主程序中可能还需要保留这些对象,或者后续操作是否需要?例如,在FORM中释放了new_sheet,那么在循环的下一次迭代中,是否还能正确使用它? 例如,主程序中调用PERFORM fill_excel_data USING new_sheet ...,然后在子程序中执行FREE OBJECT new_sheet,这会导致new_sheet对象被提前释放,可能影响后续的操作,或者导致错误。 这是可能的错误原因之一。因为在子程序中释放了主程序传递过来的new_sheet对象,这会导致该对象在子程序结束后变为无效,而主程序可能后续还需要使用它。过,在当前的代码中,主程序在调用FORM之后没有进一步使用new_sheet,所以可能问题大。但需要确认是否正确释放了对象,或者是否存在多次释放的问题。 另外,子程序中还释放了last_sheet、source_sheet、sheets、workbook等对象,这些对象可能是在主程序中创建的,子程序中是否应该释放它们?这可能导致主程序中的这些对象被意外释放,导致后续循环中的操作失败。例如,第一次循环中,子程序释放了sheets,那么第二次循环中再次GET PROPERTY OF application 'Worksheets' = sheets 时,可能因为之前的sheets已经被释放而出现错误。 这应该是一个严重的错误。因为子程序中的FREE OBJECT操作释放了主程序中的对象,导致后续循环无法正确运行。例如,第一次循环结束后,子程序里的FREE OBJECT sheets会导致主程序在第二次循环中再次尝试获取sheets时出现错误,因为对象已经被释放了。 因此,主要的错误可能在于: - 在FORM fill_excel_data中错误地释放了主程序中的对象,如new_sheet、last_sheet、source_sheet、sheets、workbook等。这会导致后续循环中的操作失败,因为这些对象已经被释放,再次使用会导致OLE异常。 例如,主程序在第一次循环中创建了这些对象,并传递给子程序,子程序执行完后释放了它们。当循环进入第二次迭代时,主程序再次尝试获取这些对象,但之前的对象已经被释放,导致错误。 因此,正确的做法应该是,在子程序中只释放子程序内部创建的对象,如cell和font,而应该释放主程序传递进来的对象,如new_sheet、last_sheet等。 此外,检查是否在复制工作表后正确获取了新工作表。例如,复制工作表后,新工作表的索引是sheet_count + 1,但
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值