Tag: 办公自动化

全局键盘挂钩(Excel)自动插件(不是VSTO)

道歉的这篇文章的长度,但我认为背景是必要的,以传达我想要实现的。 我负责更新一个旧的Excel UDF插件(它以前使用Steve Dalton的书中的JNI代码,几乎可以想象得到其他技术)。 这些函数对Excel的计算模型非常不感兴趣 – 这些函数需要几个范围,并在允许用户编辑这些数据(然后保存并上传到远程服务器)的同时(在另一个线程中)写回数据。 所有这些使得加载速度非常缓慢,但是给用户提供了必要的灵活性来根据需要改变数据。 我已经将它迁移到C#(它通过WSDL从远程Java服务器获取数据),但是我发现大多数函数被调用了50次以上,并且运行速度远远低于原始插件(这是一个使用自动插件Extensibility.IDTExtensibility2 – 所以没有VSTO技巧可用)。 在绝望的情况下,我决定尝试将UDF的块重写为数组函数,而不是接受input(Excel会抱怨覆盖数组) – 显然这比现在的用户快了几个数量级,但是缺less关键要求能够修改输出数据。 实现Excel没有提供任何之前编辑是提交validationcallback事件(我玩过Worksheet.OnEntry并添加了一个VBComponent,但它没有被触发之前有关覆盖数组或列表数据validation的错误)。 我认为这将是足够简单的实现一个全局的键盘钩子,所以开始编写一些Windows窗体来拦截编辑(只是一个文本框单个表单条目和一个combobox单元格与列表数据validation),也得到它从剪贴板复制数据所选范围。 目前,所有这一切都是由定制的上下文菜单项(或双击)驱动的,这将不会被用户所接受 – 我必须至less能够拦截F2,Ctl + V并直接在活动单元格上打字。 但我不知道如何在自动插件中注册全局键盘钩子。 所以我的问题是, 是否有可能拦截每一个编辑尝试,并提供我自己的处理? 或者失败了,我如何注册一个全局的键盘钩子来拦截F2,Ctl + V并直接在活动单元格上打字? 我试过在这里find的钩子在WPF / C#中使用全局键盘钩子(WH_KEYBOARD_LL),但无法获得App.xaml + App.xaml.cs在这种情况下工作(这是我第一次遇到C#和Windows编程一般) ,所以可能有人需要启发我的App.xaml + App.xaml.csconfiguration()。 请注意; 这不是一个VSTO插件,它使用Extensibility.IDTExtensibility2实现。 更新编辑: @TimWilliams和@CharlesWilliams询问为什么我以前的版本 ,它读写它的函数的参数,有这么多重复的调用。 所有的function都有一个强制性的ID键参数,大部分也取一个date或date范围,下面是发生了什么(在相当大的工作簿〜30张图): 当第一次加载工作簿时,函数会调用所有的过期值(先前保存的)值,但是这些值都被忽略,因为每个函数中的C#的第一行是对备份模型的(快速)testing,以查看模型是否已经加载,没有函数参数被检查/解组。 用户select通过web服务或以前的序列化文件加载模型。 可视化更新被禁用,并且设置表按照顺序填充一些数据; 一些关键的date(date的开始和结束 – 不同的date范围在不同的纸张上用EMONTH +/- 12计算),一些其他的静态数据(作者/编辑者名字等等),最后是强制性的键ID(标识模型数据) 现在,自动化插件中的每个函数的方法都有id键,所以如果find数据,它将返回,否则将使用来自函数参数的默认值。 (注意:模型维护函数所请求的对象字段的副本,以便知道输出的内容。对于进一步的调用,如果数据存在于caching层中,它将被更新(原始模型数据或先前caching值)与传入的函数参数 – 高速caching层和模型数据的差异后来上传到web服务) – 没有很好地解释“caching”实际上是一个包装模型数据相同的数据结构 […]

Excel 2010连接string?

我正在使用OLEDB连接到Excel 2010.什么是此操作所需的连接string?

为date设置Excel NumberFormat忽略本地C ++中的区域设置

我从本地C ++使用Excel COM自动化。 我的目标是设置date范围的NumberFormat。 问题是,Excel预期的格式string取决于用户的区域设置。 例如:如果语言环境是英语,我必须将NumberFormat设置为“dd.mm.yyyy”如果语言环境是德语,我需要使用“TT.MM.JJJJ”来获得相同的结果。 我发现很多.NET的解决scheme,不幸的是我没有那么奢侈。 通常的解决scheme是将Excel线程的语言环境临时设置为英文,但对于本地C ++来说似乎不可能。 我可以读取默认的系统语言环境,然后硬编码不同的格式string,但是一旦有人使用我没有明确包含的语言环境,就不会工作,所以这是一个不好的解决scheme。 那么,我该如何解决这个问题,所以无论使用哪种语言环境,它都能正常工作?

Visual Studio迫使我使用完整的命名空间,即使添加了引用并添加了“using”

我使用VS2013社区复制和我已经下载的Excel库,它仍然强迫我写整个命名空间,每次都说不能区分winforms.application()和excel.application。 它还说,“missing.value”中的“失踪”没有上下文。 此代码几乎完全从MS网站复制。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using Microsoft.Office.Interop.Excel; namespace ExcelAuto { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //Initiate Excel Objects //XlMSApplication oXL; Microsoft.Office.Interop.Excel.Application oXL; Workbook oWB; Worksheet […]

Excel应用程序在内存中不断增长

我在IIS上有一个ASP.net应用程序。 在这个程序中,我创build了一个Excel应用程序 using Excel = Microsoft.Office.Interop.Excel; public Excel.Application ExlApp; // public Excel.Workbook ExlWb; // public Excel.Worksheet ExlWs; 在申请工作中,我创build了一个新的工作簿,最后,我销毁了我的对象: GC.Collect(); GC.WaitForPendingFinalizers(); Marshal.ReleaseComObject(ExlWs); ExlWb.Close(Type.Missing, Type.Missing, Type.Missing); Marshal.ReleaseComObject(ExlWb); 问题:在工作期间,EXCEL进程正在内存中成长,我怎样才能closures工作簿?

在Excel自动化中使用非本地化的公式

我一直在玩基本的Excel自动化使用COM接口,主要利用IDispatch::Invoke 。 我的testing涉及在新创build的Excel文档中添加一个公式。 使用devise的包装库,它看起来像这样: sheet.getObject( "Range", "A1" ).set( "Value", 23 ); sheet.getObject( "Range", "A2" ).set( "Value", 42 ); sheet.getObject( "Range", "A3" ).set( "Formula", "=SUMME(A1:A2)" ); // WTF? 注意:我在这里使用(德语)本地化的公式名称SUMME ,而不是预期的标识符SUM 。 在Excel中对macroslogging器进行相同操作时,生成的VBA代码将包含SUM 。 在我的C ++代码中使用SUM ,我结束了#NAME? 在Excel中的错误。 微软的Range.FormulaLocal财产文件说明如下: 返回或设置对象的公式,使用用户的语言中的 A1样式引用。 (重点是由我做的)。 所以我希望使用Formula而不是FormulaLocal我可以解决这些本地化的困境,但显然情况并非如此。 有没有什么办法可以使用非本地化的公式? 我猜想有一些很好的隐藏设置。

Excel更改图表公式

我目前正在使用Office对象模型生成Excel文档。 我在编辑图表时遇到问题。 在一个模板文件中,我得到了一个使用以下源代码的条形图: 2008 2009 2010 A 10% 25% 15% B 20% 25% 35% C 30% 25% 45% D 40% 25% 5% 图表有以下公式:= sheet2!$ A $ 1:$ D $ 5 例如,当“2009”列是空的,我不想在图表中显示栏。 所以我想把公式改成:= sheet2!A $ 1:D $ 5; sheet2!C $ 1:C $ 5 我知道有一个方法setSourceData,但我需要先获得当前的公式或范围。 我的问题是 我怎样才能得到图表公式? 或者也许还有另一种方法来做我想要的? 我也在Excel中尝试过使用dynamic范围,但是这似乎只适用于从范围末尾添加或删除的列,而不是像列“2009”中的那样。

使excel在单个打印作业中打印多个工作表

我正在使用COM自动化打开一个xls文件并将其打印到虚拟PDF打印机。 Sheets sheets(m_Application.GetSheets()); sheets.PrintOut(CovOptional,CovOptional,CovOptional,CovOptional,COleVariant(_T("My PDF Printer")),CovOptional,CovOptional); 但是,如果文件有多个工作表,excel为每个工作表创build一个单独的打印作业,所以我得到了几个PDF文件而不是一个。 我如何强制它打印一个打印作业中的所有纸张?

从VB.NET应用程序调用Excel时,如何让Excel出现在应用程序的前面?

我有一个VB.NET应用程序,它使用Microsoft.Office.Interop.Excel来简单地打开一个电子表格,抽取一些数据到它,刷新数据透视表中的数据,然后用电子表格呈现给用户。 代码非常简单(error handling未显示): ' Start Excel Application xlApp = New Excel.ApplicationClass ' Get Excel Workbooks xlWorkBooks = xlApp.Workbooks ' Open workbook xlWorkBook = xlWorkBooks.Open(Filename:=sExcelDocFullPath, IgnoreReadOnlyRecommended:=blnIgnoreReadOnly) If Not xlWorkBook Is Nothing Then ' Pump some data over (code not shown) ' Make the first worksheet in the document active CType(xlWorkBook.Worksheets(1), Excel.Worksheet).Activate() 'Return control of Excel to […]

使用VBA自动单击消息框

我为我公司的插件自动化testing用例。 在其中一个testing用例中,当我尝试closures工作簿时,将工作簿保存在本地计算机上之后,我需要点击“是” – 将编辑后的数据保存在我们的数据库中,否 – 放弃编辑或“取消”只需closures消息框。 我曾尝试使用sendKeys,但没有为我工作。 例如:对于通过我的VBA代码点击“否”,我试图发送标签,并input这样的键: Application.Wait (Now() + TimeValue("00:00:10")) Call SendKeys("{TAB}", True) Call SendKeys("{ENTER}", True) 我用各种时间价值尝试过,仍然没有取得任何成就。 如果有人能帮助我,我会很高兴。 提前致谢! 🙂 更新:截至目前,我一直这样做: 'Some tasks… ActiveWorkbook.Save Call Application.Run("workbook.xlsm!Discard") Application.DisplayAlerts = False ActiveWorkbook.Close SaveChanges:=False Application.DisplayAlerts = True 但有没有办法获得消息框的窗口对象引用? 或者无论如何要坚持工作stream程:编辑工作簿 – >保存 – >尝试closures – >select丢弃/提交更改数据库? 注意:通过丢弃/提交对数据库的更改,我的意思是数据更新的服务器。 Excel只是用户的一个界面。 我不希望只保存excel,而是在服务器上调用丢弃/保存更改的操作。