我的女朋友在分销网络中从事采购。 最近,公司经历了大幅裁员,因此每个员工的工作量急剧增加。 因此,她不得不定期上班,有时甚至在周六外出。 她的同事们也有同样的问题。

关于允许我的女友按时返回家园的决定,您可以阅读以下内容。
此外,他们所做工作的很大一部分可以实现自动化:从前端接收数据,填写excel文档,在前端更新数据等。
在这种情况下,可以做的最合理的事情是编写有关必要功能开发的工作说明,并通过授权将其传递给开发人员。 但是,减少影响了所有人,包括开发人员。 结果,他们没有足够的资源来实现这种自动化。 而且该公司没有计划在可预见的将来购买专门的RPA系统。
此外,对员工的工作方式和工作方式的监控也得到了加强。
基于所有这些不利情况的结果以及我迫切希望提供帮助的结果,我决定在VBA中编写Excel的函数,因此有可能使我的女友及其同事的日常操作自动化。
产品要求
作为起点,我根据女孩的感觉选择了女孩花费大部分时间的任务。 作为此任务的一部分,女孩需要:
- 将商品编号从excel文件传输到前台系统搜索栏;
- 对于本文,从搜索结果中获取购买价格,销售价格以及许多其他值;
- 在excel中处理收集的数据以创建最终产品价格;
- 将价格上传回系统。
- 每天卸载和随后的数据加载大约花费了3个小时。
鉴于我的女友不具备编程知识,因此有必要使用excel中的函数形式制作具有简单且熟悉的界面的工具。 动作序列应简单地定义为功能序列。 总之,
KISS 。
基于这种情况,我形成了以下功能要求:
- 控制鼠标(移动,击键)以在屏幕上突出显示相应的元素;
- 模拟键盘上的击键以输入数据;
- 将数据从Excel传输到第三方应用程序;
- 从Excel中的应用程序检索数据;
- 在Excel中提取公式时执行相同的操作。
鼠标和第一个困难
在将光标移动到任何地方之前,您需要确切地了解将光标移动到何处。 在我看来,最简单的方法是记住光标在某个元素上方时的位置。 为了记住坐标,我使用了user32库中的GetCursorPos函数。
好了,我们得到了坐标,现在记住它们会很好。 好吧,我认为没有什么复杂的,只需从活动单元格中计数一个或两个单元格并写下坐标X和Y即可。但是,ActiveCell.Offset(0,1).Value = x不起作用。 该值未更改。 并且由于执行结果而产生错误。 在检查了各种假设之后,事实证明,更改工作表上的值会导致整个工作表的重新计数,并因此导致了重新计算的公式。 为了绕开此限制,有必要用Evaluate替换这些调用,而不是直接从某些动作的函数直接调用,这使我们获得了所需的结果。
结果是PrintCursorPosition()函数,该函数在执行该函数时记录在光标位置右侧的两个单元格中。 必须在用于输入公式的区域中键入PrintCursorPosition(),移动光标,然后按键盘上的Enter。
为了移动鼠标,我使用了来自同一user32库的SetCursorPos。 为了使用此功能,它需要传递先前存储到它的x和y坐标的值作为输入。 使用SetCursorPosition(x,y),我能够将光标移动到先前存储的坐标上。 第一个可见结果。 万岁!
为了模拟鼠标动作,我使用了来自同一user32库的mouse_event。 通过将键的标志传递给输入,我可以模拟相应键的击键。 最初,我计划编写一个函数MouseButtonPrees(flag),其中flag是所按下键的名称,但是在第一次演示之后,女孩意识到最好替换函数组LeftClick(),RightClick()和DoubleClick()。 这种方法使读取结果函数更加容易。
琴键
在VBA中,有一个执行所有必要操作的SendKeys语句。 文本可以通过引用单元格轻松传递给函数,并且可以毫无问题地实现。 但是,按特殊键(Enter,Tab,Alt,Ctrl,键盘箭头等)会导致拒绝(要按这些键,必须将它们写在大括号{ENTER}中)。 因此,对于最常用的功能,我编写了诸如PressEnter()之类的功能。 对于很少使用的文档,我在同一文档中创建了备忘单。
信息通过复制到缓冲区并从缓冲区粘贴而在系统和Excel之间传输。 复制到缓冲区实际上是通过模拟按Control + C进行的,然后将缓冲区中的数据放入MSForms.DataObject并传输到特定的单元格。
测试和性能问题
问题立即开始。
编写脚本动作序列的过程包括制定小组动作并将它们组合为一个动作。 但是,当切换到空闲单元时,整个序列会立即计算出来,这非常烦人,特别是如果一组动作花费的时间超过10秒。 为了解决此问题,我检查了函数名称的活动单元格的公式文本中是否存在该函数。 它有帮助。
此外,在测试过程中,他添加了等待功能WaitS(秒)和WaitMS(毫秒),以便跟踪有效的方法和无效的方法。 它基于kernel32库中的Sleep。 WaitS和WaitMS之间的区别在于,WaitMS中的时间以毫秒为单位,而WaitS中的时间以秒为单位。
另一个问题是,当放入单元格时,功能执行的不一致。 这是由于Excel的异步计算。 他将每个单元的计算分配给不同的处理器。 结果,该序列首先在单元格2中执行,然后在第五个单元格中执行,然后在第三个单元中依次执行,依此类推。 而且,序列本身是从头到尾进行的,没有任何问题。 为了摆脱这种行为,我在Excel设置(Excel设置->高级->公式)中关闭了多线程计算。
结果
在解释了如何使用所有这些方法并学习了如何使用它之后,他释放了女友,以这种忘恩负义的方式使公司的流程自动化。
归功于这种自动化,事实证明可以将时间从3小时减少到30分钟。 同时,自动化使得可以略微更改上传和下载数据过程的方法。 现在,卸货发生在我的女朋友去吃午饭,晚上装货的时候。 因此,我们可以说工作量减少了几乎一半的工作日,这使我的女友可以按时回家,我们可以做的事情比自动化还多。