首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >BarTender项目-导出打印机代码模板

BarTender项目-导出打印机代码模板
EN

Code Review用户
提问于 2018-12-11 16:31:14
回答 1查看 788关注 0票数 1

后续代码:酒保项目-导出打印机代码模板-跟踪

第二版:酒保项目-导出打印机代码模板-跟踪-2

正如问题中所述,我有一个有效的C#项目。

该项目的目标是打开应用程序BarTender并导出打印机代码模板(从连接到BarTender的数据库获取信息的一种方法)。我想做一些改进(即语法或构建质量/速度)。

任何一般的提示或实践将是令人敬畏的!

代码语言:javascript
运行
复制
using System;

namespace BarTender
{
    class btExport
    {
        // Dummy Variable
        private const string DataExportPath = "";   

        static void Main(string[] args)
        {
            ///////////////////////////////////////////////
            /*          VARIABLE DECLARATION            */
            //////////////////////////////////////////////

            // Declare a BarTender application variable
            BarTender.Application btApp;

            // Declare a BarTender document variable
            BarTender.Format btFormat;

            // Declare a BarTender printer code template variable
            BarTender.PrinterCodeTemplate btPCT;

            // Declare a BarTender verification variable
            BarTender.Verification btVerification;

            // Declare a BarTender messages variable to hold all messages
            BarTender.Messages btMessages;

            // Declare a variable to hold message text
            string btMessageText = "";

            // Declare a success variable
            bool ExportSuccess = true;

            // Declare an object variable
            System.Object obj = null;

            // Used for manual input
            string input = null;
            string output = null;



            ///////////////////////////////////////////
            /*          START OF BARTENDER SIDE      */
            ///////////////////////////////////////////

            // Only start BarTender when needed, otherwise use old instances
            try
            {
                // Store this instance as an object variable in C# 

                object btObject = System.Runtime.InteropServices.Marshal.GetActiveObject("BarTender.Application");

                // Convert the object variable to a BarTender application variable 

                btApp = btObject as BarTender.Application;
            }
            catch
            {
                btApp = new BarTender.Application();
            }

            // Set the BarTender application visible
            btApp.Visible = true;






            ////////////////////////////////////////

            /*             START LOGIC        */

            ////////////////////////////////////////

            // If run without parameters this 'if' is triggered for manual entry
            if (args.Length == 0)
            {
                Console.WriteLine("No parameters specified. \n Enter manually or try again.");
                Console.Write("Input: ");
                input = Console.ReadLine();
                int start = input.Length - 4;
                output = input.Remove(start, 4);
                output = output += "prn\"";
                Console.WriteLine(output);
            }
            // Taking parameters from Main
            else
            {
                input = args[0];
                Console.WriteLine("Input File Path:" + input);
                output = args[1];
                Console.WriteLine("Output File Path:" + output);

            }

            // Open a BarTender document
            try
            {
                btFormat = btApp.Formats.Open("\"" + input + "\"", false, "");

                // Specify the password to remove print-only protection from the application 

                btApp.SpecifyPrintOnlyPassword("#Betsy");

                // Set the printer code template variable
                btPCT = btFormat.PrinterCodeTemplate;

                // Export the printer code template
                btPCT.Export("SAPscript-ITF", BarTender.BtPctExportType.btPctExportCombined, output, DataExportPath, ref obj);
            }
            catch { Console.WriteLine("Input or Export file does not exist."); Console.ReadLine(); return; }

            // Set the messages variable to the object
            btMessages = obj as BarTender.Messages;

            // Check to see if there is an error message
            if (ExportSuccess == false)
            {
                // Loop through the messages
                for (int i = 1; i <= btMessages.Count; i++)
                {
                    // Get the error message
                    btVerification = btMessages.GetMessage(1).Verification;

                    // Populate the error messages into a string
                    btMessageText = btMessageText + btVerification.Problem + "\r\n" + btVerification.Fields + " " + btVerification.AutoFix + "\r\n" + btVerification.Result;

                }
            }
            else
            {
                // Loop through the messages
                foreach (BarTender.Message btMsg in btMessages)
                {
                    // Get the error message
                    btVerification = btMessages.GetMessage(1).Verification;

                    // Populate warning messages into a string
                    btMessageText = btMessageText + btVerification.Problem + "\r\n" + btVerification.Fields + " " + btVerification.AutoFix + "\r\n" + btVerification.Result;

                }
            }
            // End the BarTender process
            btApp.Quit(BarTender.BtSaveOptions.btDoNotSaveChanges);

            Console.WriteLine("Complete");
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        }
    }
}
EN

回答 1

Code Review用户

发布于 2018-12-11 20:20:07

缺陷与问题:

  • 如果input.Remove(start, 4)小于0时,start会抛出一个异常,这在input.Length小于4时会发生。您应该检查这一点,否则就会在此时捕获异常。这个输出路径逻辑似乎也是用非常具体的输入来编写的--它看起来相当脆弱。
  • 类似地,如果args[1]小于2,则args.Length将失败,但您只确保args.Length不是0,所以如果只提供一个参数,这将引发。这也会导致崩溃,因为这里没有捕获异常。
  • 无论何时使用null,始终检查是否为as。您没有在btObjectbtMessages中这样做,所以使用它们可能会导致NullReferenceExceptions
  • 最后的forforeach循环似乎都在做完全相同的事情,只是方式略有不同,所以其中一个很可能可以被删除。因为ExportSuccess总是真的,所以无论如何也不会执行for循环。无论哪种方式,这两个循环总是得到相同的消息(索引或id 1),这可能是不正确的。

Readability:

  • 有很多不必要的评论。像'delare a TypeName变量‘这样的东西是没有用的,并且有更好的方法来了解代码正在做什么,而不是使用'shouty’头。尝试使用注释来解释为什么代码会这样做--通过查看代码本身,它所做的事情应该是显而易见的。
  • 正如Andy已经提到的,尝试将您的主要方法分成几个方法,每个方法都有特定的目的。GetApplicationGetInputOutputPathsExportCodeTemplateShowErrorMessages似乎是一种合理的做法。这保持了Main的简短和简单,并且快速地向您提供了应用程序实际操作的高级概述--不需要任何评论。
  • 为什么所有变量都是预先声明的?我会把它们移动到每个变量实际使用的位置。最好在尽可能小的范围内,并在可能时立即初始化。这使得相关的事情在一起,这将使代码更容易理解。
  • 有一个catch语句体,包含几个语句,包括一个return,所有语句都在一行上。这种不一致使得代码更难以阅读。将每条语句放在单独的一行上。

其他注释:

  • btMessageText不在任何地方使用。在任何情况下,通过附加到StringBuilder来实现字符串的连续连接更有效。
  • variable1 + "small string" + variable2这样的东西可以用插值的字符串编写得更简洁:$"{variable1}small string{variable2}"
  • variable == false,其中variable是一个布尔值,而不是一个可空的布尔值,通常被写成!variable
  • 尝试使用更多的描述性名称。inputoutput都很好,但是inputFilePathoutputFilePath更好。objbtObject是糟糕的名字-- messages (甚至exportErrorMessages)和application更好。在大多数情况下,不需要缩写事物(printerCodeTemplate而不是PCT),而且bt前缀没有添加任何真正的值,很容易与button混淆,就像Andy已经指出的那样。
  • btPCT是不必要的:您可以直接调用btFormat.PrinterCodeTemplate.Export(...)
  • 我会用using System.Runtime.InteropServices代替写Marshal's的全名。
  • 为什么密码是硬编码的,而不是作为参数或通过用户输入传入的?
  • 为什么代码中只有一部分是在try-catch语句中呢?
  • 就我个人而言,我会更多地使用C#'s类型推断(var),特别是因为在大多数赋值中,这种类型在左右两面都是明显的。
票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/209457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档