首页 > 其他分享 >在Excel中绘制ActiveX控件:解决文本编辑框定位问题

在Excel中绘制ActiveX控件:解决文本编辑框定位问题

时间:2024-12-19 12:57:49浏览次数:6  
标签:控件 False ActiveX 定位问题 Top Range textbox3 ws Left

目录

引言

问题描述

解决方案

方法1:使用Range对象的Left和Top属性

方法2:使用相对位置

方法3:使用单元格作为参考

结论

代码实现


​​​​​​​引言

在Excel中添加ActiveX控件,如按钮和文本编辑框,可以极大地增强工作表的交互性。然而,定位这些控件可能会遇到一些挑战。在本文中,我将分享我如何通过调整代码解决了文本编辑框始终定位在左上角的问题。

问题描述

在尝试将ActiveX控件添加到Excel工作表时,我发现按钮可以成功定位到指定位置,但文本编辑框始终固定在左上角。这个问题让我头疼了好几天,直到我找到了解决方案。

解决方案

经过大量资料查找和尝试,我找到了三种不同的方法来定位文本编辑框。以下是每种方法的测试代码和结果:

方法1:使用Range对象的Left和Top属性

这种方法直接使用Range对象的LeftTop属性来设置文本编辑框的位置。

textbox1 = ws.OLEObjects().Add(ClassType="Forms.TextBox.1", Link=False, DisplayAsIcon=False,
                Left=left, Top=top, Width=100, Height=20)

然而,这种方法并没有奏效,Textbox1的位置仍然显示为Left: 0.0, Top: 0.0

方法2:使用相对位置

这种方法尝试通过在Left属性上加上一个偏移量来定位文本编辑框。

textbox2 = ws.OLEObjects().Add(ClassType="Forms.TextBox.1", Link=False, DisplayAsIcon=False,
                Left=left + 120, Top=top, Width=100, Height=20)

不幸的是,这种方法同样未能解决问题,Textbox2的位置依然是Left: 0.0, Top: 0.0

方法3:使用单元格作为参考

在尝试了上述两种方法后,我终于找到了正确的方法。这种方法通过将文本编辑框的位置设置为特定单元格的位置来实现定位。

textbox3 = ws.OLEObjects().Add(ClassType="Forms.TextBox.1", Link=False, DisplayAsIcon=False)
textbox3.Top = ws.Range("E3").Top
textbox3.Left = ws.Range("E3").Left
textbox3.Width = ws.Range("E3:F3").Width
textbox3.Height = ws.Range("E3").Height

这种方法成功地将Textbox3定位到了预期的位置,输出结果显示Left: 192.0, Top: 27.6

结论

通过对比三种方法,我们可以清楚地看到,第三种方法是正确的解决方案。这个问题的解决让我感到非常开心,因为它不仅提高了我的编程技能,还增强了我对Excel ActiveX控件的理解。

代码实现

以下是完整的代码实现,包括创建Excel实例、添加工作簿、定位控件以及添加VBA代码。

import os
import win32com.client
import pywintypes

def create_excel_with_controls(output_path):
    try:
        # 创建 Excel 实例
        excel = win32com.client.DispatchEx("Excel.Application")
        excel.Visible = False  # 设置 Excel 为不可见

        # 创建工作簿并获取第一个工作表
        wb = excel.Workbooks.Add()
        ws = wb.Worksheets(1)
        ws.Name = "Prediction Results"  # 设置工作表名称

        # 写入表头
        ws.Cells(1, 1).Value = 'i'
        ws.Cells(1, 2).Value = 'c'
        ws.Cells(1, 3).Value = 's'
        ws.Cells(1, 4).Value = 'l'

        # 获取 E1 单元格的 Range 对象
        cell_range = ws.Range("E1")
        left = cell_range.Left
        top = cell_range.Top
        print(f"E1 Cell Position - Left: {left}, Top: {top}")

        # 方法1:使用 Range 对象的 Left 和 Top 属性
        textbox1 = ws.OLEObjects().Add(ClassType="Forms.TextBox.1", Link=False, DisplayAsIcon=False,
                    Left=left, Top=top, Width=100, Height=20)
        textbox1.Name = "ThresholdTextBox1"
        print(f"Textbox1 Position - Left: {textbox1.Left}, Top: {textbox1.Top}")

        # 方法2:使用相对位置
        textbox2 = ws.OLEObjects().Add(ClassType="Forms.TextBox.1", Link=False, DisplayAsIcon=False,
                    Left=left + 120, Top=top, Width=100, Height=20)
        textbox2.Name = "ThresholdTextBox2"
        print(f"Textbox2 Position - Left: {textbox2.Left}, Top: {textbox2.Top}")

        # 方法3:使用单元格作为参考
        textbox3 = ws.OLEObjects().Add(ClassType="Forms.TextBox.1", Link=False, DisplayAsIcon=False)
        textbox3.Top = ws.Range("E3").Top
        textbox3.Left = ws.Range("E3").Left
        textbox3.Width = ws.Range("E3:F3").Width
        textbox3.Height = ws.Range("E3").Height
        textbox3.Name = "ThresholdTextBox3"
        print(f"Textbox3 Position - Left: {textbox3.Left}, Top: {textbox3.Top}")

        # 添加按钮
        button = ws.Shapes.AddFormControl(Type=0, Left=ws.Range("G1").Left, Top=ws.Range("G1").Top, Width=100, Height=20)
        button.Name = "SetThresholdButton"
        button.TextFrame.Characters().Text = "确定"
        print(f"Button Position - Left: {button.Left}, Top: {button.Top}")

        # VBA 代码
        vba_code = '''
        Private Sub SetThresholdButton_Click()
            Dim threshold_value As String
            threshold_value = Me.ThresholdTextBox1.Text
            If threshold_value <> "" Then
                Me.Range("F5").Value = "已设置: " & threshold_value
            Else
                MsgBox "请输入", vbExclamation
            End If
        End Sub
        '''

        # 将 VBA 代码添加到工作簿的代码模块
        vba_code_module = wb.VBProject.VBComponents("ThisWorkbook").CodeModule
        vba_code_module.AddFromString(vba_code)

        # 保存工作簿
        if not os.path.exists(output_path):
            os.makedirs(output_path)
        excel_file_path = os.path.join(output_path, 'example_with_activex.xlsm')
        wb.SaveAs(excel_file_path, FileFormat=52)  # FileFormat=52 指定 .xlsm 格式

        # 关闭工作簿并退出 Excel
        wb.Close(SaveChanges=False)
        excel.Quit()
        print("Excel file created successfully.")

        return excel_file_path
    except pywintypes.com_error as e:
        print(f"COM Error: {e}")
        print(f"HRESULT: {e.hresult}, Description: {e.strerror}")
    except Exception as e:
        print(f"Error: {e}")

# 使用函数
output_path = 'D:\\'  # 请确保此路径存在或有权限创建
created_file = create_excel_with_controls(output_path)
print(f"Created file: {created_file}")

希望这篇文章能帮助那些在Excel中遇到类似问题的朋友们。

如果你有任何疑问或需要进一步的帮助,请咨询我。

标签:控件,False,ActiveX,定位问题,Top,Range,textbox3,ws,Left
From: https://blog.csdn.net/weixin_45037357/article/details/144583463

相关文章

  • 06. 标签控件
    一、标签控件  QLabel控件,又称为标签控件,它主要用于显示用户不能编辑的文本,标识窗体上的对象(例如,给文本框、列表框添加描述信息等)。  我们可以在终端中使用pip安装pyside6模块。pipinstallpyside6label=QLabel()  创建好的标签控件,我们可以调用show()方......
  • WPF 集合控件虚拟化操作
    一、虚拟化WPF列表控件所提供的最重要的功能就是UI虚拟化。1、UI虚拟化技术其实就是只为可见区域中能显示的项创建容器对象的一种技术,对提升列表控件的性能有着显卓的效果。假设有一个数万条记录的数据,其可见区域只能展示30条记录仪,此时如果使用虚拟化技术,那么界面只需要创建30个......
  • 安卓开发学习5 - 安卓简单控件+部分androidStudio快捷键+去除默认主题+实战简单计算器
    按钮-Button按钮控件button由textview派生而来,二者区别:button拥有默认的按钮背景,而textview默认无背景button的内部文本默认居中对齐,而textview的内部文本默认靠左对齐button会默认将英文字母转为大写,而textview保持原始的英文大小写与textview相比,button增加了两个新......
  • 安卓移动设备软件开发期末复习(1) 控件
    监听器监听器是事件监听机制的重要组成部分。在Java中每类事件都定义了一个相应的监听器接口,该接口定义了接收和处理事件的方法。实现该接口的类,其对象可作为监听器对象注册在事件源组件上。在图形用户界面中,需要响应用户操作的相关组件要注册一个或多个相应事件的监听器......
  • XSYL10103利用控件获取值也可以用自定义
    stringCKID=this._page.GetControlValue("btnCKMC");pu10103,btnCKMC是一个下拉框namespaceXSYLKCGL{publicclassCKWLDY:ISuwfBus{///<summary>///initialization///</summary>privateSlnS......
  • 界面控件Kendo UI for Angular中文教程:如何构建带图表的仪表板?(三)
    KendoUIforAngularListView可以轻松地为客户端设置一个带有图表列表的仪表板,包括分页、按钮选项、数字或滚动,以及在没有更多项目要显示时的通知等。KendoUIforAngular是专用于Angular开发的专业级Angular组件。telerik致力于提供纯粹的高性能AngularUI组件,无需任何jQuery......
  • 【帆软Report】关于按钮控件的使用
    在帆软使用过程中,会遇到一些需求,比如某个功能,某些页面要在特定情况下才可以使用,这篇主要是对按钮在特定情况下显示和隐藏的心得先说需求:有一个打分按钮,要求实现当传入的状态编码是“1”的时候可以看到并且点击,其他状态编码时按钮无法使用并且隐藏。实现方法如下:在帆软e......
  • QT自定义控件实践--滑动组件
    概述             本篇文章,会逐步带您了解,如何自定义一个QT的滑动组件操作步骤选择合适的基类继承:我们命名这个自定义控件为MySlipButton,继承自QWidget添加成员变量:根据滑动组件的特性,添加合适的成员变量,如当前值、最小值、最大值、滑块的位置等。......
  • Qt实现控件拖曳
    DragTreeWidget.h#ifndefDRAGTREEWIDGET_H#defineDRAGTREEWIDGET_H#include<QTreeWidget>classQMouseEvent;classDragTreeWidget:publicQTreeWidget{Q_OBJECTpublic:DragTreeWidget(QWidget*parent=nullptr);private:voidinit()......
  • 源码分析之Openlayers中的控件篇Control基类介绍
    概述Openlayers中内置了9类控件,这9类控件都是基于Control类,而Control类则是继承于BaseObject类,如下图所示:如上,这9类控件分别是:Attribution:属性控件FullScreen:全屏控件MousePosition:鼠标位置控件OverviewMap:鹰眼控件Rotate:旋转控件ScaleLine:比例尺控件Zoom:缩放控件,可......