从VBA到C#的团队成员质疑


20

背景

去年,我被要求为大约10个用户创建一个用于业务计划的工具。这项工作是由另一个IT团队代表完成的,该团队将工作“分包”给我,并且由于项目期限在他们这边有些计划外,我不得不匆忙实施。

当时,我们决定最快的方法是使用VBA创建Excel工作簿,然后让用户从Intranet下载此VBA增强的工作簿以在其PC上使用。在这种情况下,Excel是一个约束,因为我们使用的计划系统(即数据库)只能通过Excel加载项进行交互,该加载项必须在打开计划工作簿的同时加载。但是,当时VBA并不是一个约束。

我创建了约4,000行VBA代码的工作簿,虽然我尝试分离数据层和表示层,但由于项目截止日期,所以在所有情况下都无法做到。老实说,虽然我为创建此工作簿感到自豪,但同时我感到有些失望,因为它在编码和部署到用户方面都可以做得更好。

今天

回到今天,IT团队再次来找我,要求提供类似的工作簿(这样我就可以重用上面其他工作簿的部分内容),但这一次它变得更加复杂,将被更多的用户使用( 200左右)。

但是,这次的计划要好一些,我可以看到我们有更多的时间来计划事情。基于此,我考虑了该解决方案和基础架构,因为针对100个用户的编程比对10个用户的编程影响更大。因此,我向团队建议,也许我们应该考虑将现有代码迁移到C#解决方案,以便我们可以以更精细的方式管理代码。我仍将其视为使用VSTO / Excel-DNA编写的加载项,然后可以将其部署到用户。

两周前,我与IT团队讨论了这一问题,一切似乎都很好,直到昨天,我收到一个团队(不了解VBA或C#)的邮件,询问我们为什么应该在C#中启动这个新项目,而不是使用与以前相同的方法。他们的一些担忧是:

  • 这是一个非常重要的项目,因此它必须能够工作-C#解决方案不能像现有的基于VBA的解决方案那样稳定或有效。
  • 我们将不得不舍弃[I]在VBA解决方案中所做的事情,并在C#中从头开始重新创建它。
  • 有人必须支持两种单独的解决方案,一种在VBA中,一种在C#中。[实际上,他们目前没有任何人支持,我通常会介入]。

现在,我可以在某种程度上理解他们的一些担忧,但是我需要决定下一步的工作以及如何处理这些问题。就个人而言,我想用C#实施,因为我认为它更适合于构建这样的“企业”解决方案。此外,我想借此机会提高我的C#技能,因为我目前不像VBA那样胜任C#的能力,并且我希望通过这样的项目将我带入“下一个级别”。

我准备了一些要点,可以用来说服他们说C#解决方案更适合该项目,这是我到目前为止的目标:

  • 单元测试。
  • 源代码控制。
  • 代码文档-用于将知识转移给其他支持人员。
  • 更好的编码约定-可以使用ReSharper之类的东西来加强更好的命名和结构。
  • 更好的IDE-减少由于错误突出显示而导致的错误。
  • 通过组件实现更高的模块化-可以促进将来工具的重用。
  • 托管部署-可以控制使用此工具的人员。

问题:我还能说些什么来说服他们?还是我想尽全力去完成这个项目?我应该保持安静,还是在VBA中这样做吗?

我知道,仅因为新语言的“较新”或被视为“较凉爽”而改用新语言就不应作为决策的基础,因此我拒绝将其作为决策要点-这是关于事实的。

另外,我不要求在C#和VBA作为语言之间进行字面比较,因为在SO上有很多比较。



2
我想你需要看这个。以防万一它南下,而您最终陷入了VBA。免责声明:我是该项目的开发人员之一。 rubberduck-vba.com
RubberDuck

7
为什么用C#而不是vb.net?
塔伊米尔2015年

2
我处于同样的位置,在EXCEL工作簿中内置了一个非常大的应用程序(超过20k行VBA代码)。在Office 2013上进行测试后,它简直无法正常工作,原因可能是由于新Office模型中启动事件的顺序发生了变化,并且可能更严格地实施了EMET。因此,在今年推出Office 2013之前,我可以将崩溃转换为C#和VB.NET。组织中使用的其他更简单(VBA增强)的工作簿也无法幸免,有些无法工作,有些则无法。
Pieter Geerkens 2015年

3
现在的C#和7年前的C#不一样。基于VB的语言越来越不推荐使用。如果要进行短期修复,请在VBA中进行。如果应该持续使用并在将来扩展,请使用C#。
2015年

Answers:


30

您列出的三点似乎很公平:

这是一个非常重要的项目,因此它必须能够工作-C#解决方案不能像现有的基于VBA的解决方案那样稳定或有效。

确实,稍后,您告诉您:“我想借此机会提高我的C#技能,因为我目前不如VBA那样胜任C# ”(强调我的意思)。

换句话说,您有一个可行且经过大量用户测试的解决方案。您想扔掉所有这些并用您不太熟悉的语言重写所有内容。看到问题了吗?

我们将不得不舍弃[I]在VBA解决方案中所做的事情,并在C#中从头开始重新创建它。

你不应该做的事情浮现在脑海。您将抛出代码以及用户测试。不好

有人必须支持两种单独的解决方案,一种在VBA中,一种在C#中。[实际上,他们目前没有任何人支持,我通常会介入]。

如果仍将使用VBA版本,则重写的确确实存在更多问题。为什么只有两个已经运行并且可以重构和添加功能的系统,却需要两个不同的系统来引起您的注意?


另一方面,您的一些观点可能会受到批评:

  • 单元测试。

    您也可以对当前项目进行单元测试。如果没有方便的框架,请创建一个。

  • 源代码控制。

    源代码管理处理文本。您当前的代码是文本,因此可以使用源代码控制。

    语言,操作系统,框架或生态系统完全无关。您可以(并且应该)对所编写的任何代码使用源代码管理:Visual Studio中的代码,或者您在LINQPad中几分钟后草拟的一段代码,或者用于自动执行任务的PowerShell脚本,数据库模式或Excel宏。

  • 代码文档-用于将知识转移给其他支持人员。

    同意

  • 更好的编码约定-可以使用ReSharper之类的东西来加强更好的命名和结构。

    定义“更好”。有Excel宏的编码约定吗?如果是,请使用它们:它们并不比其他任何更好或更差。如果不是,请创建并发布它们,以便其他人也可以使用它们。2010年发布的问题的答案似乎令人失望,但此后可能会有新工具可用。

    请注意,编码约定的重要部分是应在提交时强制执行它们。

  • 更好的IDE-减少由于错误突出显示而导致的错误。

    同意 很遗憾,我们无法在Visual Studio中编写宏

  • 通过组件实现更高的模块化-可以促进将来工具的重用。

    我很确定您当前的产品也可以使用某种程度的模块化。

  • 托管部署-可以控制使用此工具的人员。

    同意


除了完全重写之外,您还可以寻找一种逐步将代码从宏移动到用VB.NET编写的普通程序集的方法。为什么在VB.NET中?三个原因:

  • VBA和VB.NET之间的差异较小,因为VBA和C#之间的差异较小。

  • 您更了解VBA,仅此一个理由就可以使用VB.NET而不是C#。如果您想“掌握C#技能”,请使用您的个人项目,而不是关键业务来完成。

  • 从一种语言到另一种语言的任何重写都会导致潜在的错误。您不需要这个项目。

移至.NET程序集可以为您提供一个方便的Visual Studio环境,并具有方便的单元测试,TFS和错误突出显示您当前在其他项目中使用的功能。

同时,如果逐步移动代码,则不会冒完全重写的风险(即花四个月的时间来创建任何人都不想使用的东西,因为大量的新错误)。例如,您需要使用特定功能吗?想一想如何将该特定功能首先移至.NET。

这与重构非常相似。不必因为学习了一些新的设计模式和语言功能而重写整个内容,而只需对当前使用的代码进行少量更改即可。


7
与VBA一起使用,您最终会获得很多额外的元编程。除其他事项(测试,宏导入器/导出器等)之外,我已经编写了用于vba-excelsheets的分发工具,该工具可打开远程工作表并交换宏,运行更新宏并确保工作表再次处于正确的形状(在C#中) , 感谢上帝)。但是,我认为仅此一项比VBA代码要付出更多的努力。我并不是说您应该不惜一切代价使用C#,但是考虑迁移到更现代的平台应该符合每个人的利益。
SBI

3
VB.NET是否真的与VBA如此相似,以至于您进行替换后,第二点和第三点仍然成立?
本·亚伦森2015年

1
VB.NET的另一个优点是,您可以轻松组合使用不同.NET语言编写的组件。因此,您可以(例如)从VBA迁移到VB.NET,然后在C#,VB.NET或对您的项目有意义的任何其他功能中添加新功能。
Theodoros Chatzigiannakis 2015年

12

我会支持去C#。其他人已经很好地涵盖了您的观点,因此我不会重复他们所说的话。绝对有很多理由坚持使用VBA。

但是,我的一位雇主在创建有意义的文档方面做得很出色。如此之多,以至于实际上只有合理地写下了设计决策-如果只有所有软件项目都具备这一点!我的观点?设计决策之一是“我们选择用Java编写该程序,因为某某先生希望将x年的Java经验用于他的简历”。如果这是您迁移到C#的强烈理由,那么这是不容忽视的。这只是您用来向IT团队证明其合理性的原因之一,因为他们并不真正在乎简历上想要的东西,而是在乎工作的产品。

还有对VBA的思考。我知道这不是真的,但是我认识很多人,他们在履历表上看到“ VBA”,然后想:“什么,这个家伙被困在实习工作?为什么他没有真正的语言经验?” 他们看到“ VBA”并认为是“ excel宏开发人员”。就像将一个单元格复制/粘贴到另一个单元格,执行简单的计算等。通常,那些喜欢VBA中实际开发的人就是那些已经完成了这些工作的人,至少从我的经验来看,这似乎越来越小。您可能对您所在地区的VBA有更好的了解,但是我已经看到很多对此不公正的否定看法。

我想进行的另一件事是:MainMa提到了VBA和C#之间的相似之处。这是绝对正确的,JMK的答案提供了一些可供阅读的技术。尝试将VBA代码复制/粘贴到C#项目中,看看语法错误看起来有多容易纠正。

您说您有4,000行代码,这是一大段代码,可能包含许多功能...但是,它只有 4,000行代码。尝试复制粘贴内容。如果您可以清理这些语法错误并拥有一个有效的项目,我真的不会感到惊讶。我不知道您的代码的详细信息或可用的空闲时间,我认为您可以在周末取消这些。

它可能不遵循C#最佳实践,但效率可能不高,但是最终会在C#中获得功能上等效的项目。您还可以相对确定新的C#代码不会比旧的VBA代码更容易出现缺陷。

自行将VBA代码转换为C#可以为您做两件事:

  • 在研究语法错误时,您将更加熟悉C#实践-一种在C#中实际工作的入门
  • 在将插件加载到excel时,它将对所有明显的问题有所启发(因为excel仍然是必需的)。也许有一个您尚未考虑的问题可能是一个障碍。
  • 它将向您的客户(IT团队)显示概念证明。如果他们看到您有一个具有当前功能的可用C#插件,那么您将使用C#降低他们的感知风险水平。

回到IT的三点:

•这是一个非常重要的项目,因此它必须能够工作-C#解决方案不能像现有的基于VBA的解决方案那样稳定或有效。

如前所述,您的C#代码将涵盖相同的功能,并且与VBA一样稳定。严格说来,你介绍的错误/缺陷或低效的机会,但是这似乎不太可能。我们不是在谈论从iOS / Objective C到Android / Java的移植,而是在两种语言之间的移植,它们在语法上有很多相似之处,并且可以利用完全相同的技术-excel工作簿。

•我们将不得不舍弃[I]在VBA解决方案中所做的工作,并在C#中从头开始重新创建它。

这样,您就不会花费任何精力或代码。

•必须有人支持两种独立的解决方案,一种在VBA中,一种在C#中。[实际上,他们目前没有任何人支持,我通常会介入]。

您只有1个解决方案,全部使用C#。

总而言之,您的客户会发现很多风险。如果您可以采取措施减轻这种风险,那么他们可能会接受对C#的更改。


2
您对我的回答提出了一些非常有效的反证。++只是这样做并查看其运行方式。你是对的。该项目可能会在一个下午移植。
RubberDuck

11

我讨厌这样说,但您的论点没有成立。

单元测试。

长期以来,这一直是一个解决的问题。有许多单元测试框架。选一个。您应该已经这样做了。我推荐我们的,因为它已集成到IDE中并提供了其他出色的功能。

源代码控制

这有点困难,几乎没有现成的解决方案,但这实际上只是将代码移入或移出存储库的问题。这是一种低眉的方法,但是还有其他更好的选择

代码文件

也是解决的问题。MZ-Toolshas具有XML文档功能,其功能与.Net的XML注释文档非常相似。

更好的编码约定

就像Visual Studio具有ReSharper插件一样,MZ-ToolsRubberduck都具有此类功能。

更好的IDE

再次,有一些插件可用于VBA IDE。

通过组件实现更高的模块化-可以促进将来工具的重用。

也是解决的问题。不,您不能创建程序集,但是可以引用其他VBA项目。

托管部署-可以控制使用此工具的人员。

贴一点,您将需要编写代码来控制谁可以访问该程序以及谁不能访问该程序,但是(再次)您可能应该已经编写了安全代码。

至于部署,这也是一个已解决的问题。是的,它需要代码,但是有一些示例可以使用/修改


最重要的是,您将从头开始。我也会推荐Joel Spolsky的文章

他们通过犯任何软件公司可能犯的最严重的战略错误来做到这一点:

他们决定从头开始重写代码。

您的IT专家是正确的。您不应该从头开始重写它。您应该用当前的解决方案解决问题。

现在,尽管如此,我完全可以理解为什么要在C#或VB.Net中执行此操作。如果您要启动一个新项目,它们确实是一个更好的解决方案,但是从它的声音来看,它不是一个新项目。最好从头开始改进然后再打破它。


4

你可以指出,即使微软在声明文章:

更新代码以改善功能或修复错误将要求每位用户以及使用自定义功能的每个文件中的每个人都重新发送电子邮件,重新构造和重新处理Office工件。

这篇文章是关于基于Office开发内容的不同方法的,也许您可​​以在讨论中利用它的其他优点和缺点。


是。交付是这里的关键因素。其他所有内容都是语义。
RubberDuck

10
我个人得出一个结论,那就是您应该运行……从VBA尽可能快地运行,这有令人难以置信的原因。但是,您的用户可以理解的最佳论据之一是,由于此代码包含在电子表格中,因此每次复制文件时,也可能是一个文件,可能需要使用修复程序进行更新,这是一个手动过程。例如,如果您在9个月内发现一个重大错误,则需要更新所有受影响的文件。如果将它们分布在许多OC上,这将成为不可能完成的任务。为了保持头脑清醒,请将应用程序捆绑在Excel插件中。
RLH 2015年

我认为我不同意所有@RLH。对于许多小规模的问题,VBA仍然是明智的解决方案。当分发成为问题时,它就会失败。
RubberDuck

4

这实际上取决于您打算如何使用C#(即,您将使用什么技术)。

如果要使用OpenXML,那么您正在谈论的是完全重写,如果您有可行的解决方案,则不建议这样做。

如果您正在谈论使用Interop,您可能会发现该过程非常顺利。过去,我已经将很多代码从VBA移到了C#(使用Interop)中,一旦插入工作簿,就像这样:

var excelApplication = new Application();
var workbook = excelApplication.Workbooks.Open(@"C:\location.xlsx");

在很多情况下,您可以复制/粘贴VBA代码,在函数调用前添加前缀workbook.,在适当的地方用var等替换Dim,最后添加分号。

它本质上是相同的框架(Excel),您只是将语法从VBA更改为C#。

完成后,请确保保存并关闭该应用程序:

workbook.Save();
excelApplication.Quit();

然后与元帅一起发布该应用程序:

Marshal.ReleaseComObject(excelApplication);

我可能会在Excel Application对象周围编写一个实现IDisposable的包装器类,然后确保在使用using该对象时使用它。

进行案例分析的一个好方法是花费一个小时左右的时间,这将在很短的时间内证明您可以多么快速地移植代码,并使您的同事相信这是一个好主意。

在某种程度上,代码将保持基本不变,但是您拥有提到的在Visual Studio中拥有C#项目的所有好处。


2

我处于同样的位置,在EXCEL工作簿中内置了一个非常大的应用程序(超过20k行VBA代码)。在Office 2013上进行测试后,它简直无法正常工作,原因可能是由于新Office模型中启动事件的顺序发生了变化,并且可能更严格地实施了EMET。因此,在今年推出Office 2013之前,我可以将崩溃转换为C#和VB.NET。组织中使用的其他更简单(VBA增强)的工作簿也无法幸免,有些工作而另一些则不能。

错误发生在Workbook_Open事件中,在该事件中工作簿的表不再可用,并且在引用任何VBA代码之前在内部EXCEL代码中发生。

在所有VBA,C#和VB.NET中都感到很满意,我在后两者中都编写了转换。框架代码是用C#编写的,因为语言惯用语使我可以用该语言编写某些功能构造,比VB.NET快3-4倍。大部分代码都在VB.NET中进行,因为这样我的重写工作就不那么广泛了,并且某些惯用法在C#中不存在。

在做出任何决定之前,我强烈建议您使用OFFICE 2013测试现有应用程序,以及组织预计在未来2-3年内全面实施的EMET实施范围。您可能像我一样,发现如果不进行重写,现有应用程序将无法在该环境中运行-在这种情况下,重写也可能发生在DOT NET和VSTO中。

附录:

编写一个小的自动提取实用程序,可以遍历工作簿VBA的全部内容,并将所有模块,类和表单导出到文件中,需要1-2天的时间,具体取决于您的期望程度。同样,通过反向操作将文件从目录导入空白工作簿。通过这两个,很有可能使所有VBA代码都处于适当的源代码控制中,并有一个从工作簿的源代码进行构建的过程。

或-使用免费的实用程序,例如Excel VBA Code Cleaner


2

我想借此机会提高我的C#技能,因为我目前不像VBA那样胜任C#的能力,并且我希望通过这样的项目将我带入“下一个级别”。

说实话。您是否计划与参与此决策的其他人共享此信息?如果没有,那么如果项目失败,我会全责您。由于已经创建了一个类似的项目并将其投入领域,因此每个人都已经形成了自己期望发生的事情。他们知道构建最后一个所需的时间,并相信您可以在更短的时间内创建一个(根据其他要求,这可能是正确的,也可能不是正确的)。您准备好承担起学习新语言的责任了吗?

我建议尽快将旧应用程序移植到C#。在做出决定之前,也许您可​​以在过程中学到足够的知识。至少您将实现使用新语言提高技能的目标,并且仍能按时完成项目。

再说一次,如果您对此有足够的信心,而建设项目全都落在您的肩膀上,请按照自己的方式进行。得到宽恕总是比允许容易。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.