使用宏或VBA将科学记数法中的数字转换为Excel中的数字格式

时间:2012-04-09 14:18:36

标签: excel vba

MS Excel吃掉了我的脑袋。它将数字随机转换为科学记数法格式。当我以制表符分隔格式保存的文件加载到SQL Server时,这会导致问题。我知道我可以提供一个格式文件并做很多花哨的东西。但是,让我说我做不到。

是否有一个循环遍历所有单元格的宏,如果单元格中的数字是科学记数法格式,那么它会将其转换为数字格式吗?

说:

Input: spaces signify different cells.
1.00E13 egalitarian 

宏之后的输出:

10000000000000 egalitarian

我在Excel 2007中尝试这个。

3 个答案:

答案 0 :(得分:1)

我写了一个简单的C#程序来解决这个问题。希望它有用。

输入:

输入文件所在的目录(假设文件采用.txt格式)。

输出:

将转换文件吐出的输出目录。

分隔符:

列分隔符。

代码

using System;
using System.Text.RegularExpressions;
using System.IO;
using System.Text;
using System.Threading;

namespace ConvertToNumber
{
    class Program
    {
        private static string ToLongString(double input)
        {
            string str = input.ToString().ToUpper();

            // If string representation was collapsed from scientific notation, just return it:
            if (!str.Contains("E")) 
                return str;

            var positive = true;
            if (input < 0)
            {
                positive = false;
            }

            string sep = Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator;
            char decSeparator = sep.ToCharArray()[0];

            string[] exponentParts = str.Split('E');
            string[] decimalParts = exponentParts[0].Split(decSeparator);

            // Fix missing decimal point:
            if (decimalParts.Length == 1) 
                decimalParts = new string[] { exponentParts[0], "0" };

            int exponentValue = int.Parse(exponentParts[1]);

            string newNumber = decimalParts[0].Replace("-","").
                Replace("+","") + decimalParts[1];

            string result;

            if (exponentValue > 0)
            {
                if(positive)
                    result =
                       newNumber +
                       GetZeros(exponentValue - decimalParts[1].Length);
                else
                    result = "-"+
                     newNumber +
                     GetZeros(exponentValue - decimalParts[1].Length);


            }
            else // Negative exponent
            {
                if(positive)
                    result =
                        "0" +
                        decSeparator +
                        GetZeros(exponentValue + decimalParts[0].Replace("-", "").
                                   Replace("+", "").Length) + newNumber;
                else
                    result =
                    "-0" +
                    decSeparator +
                    GetZeros(exponentValue + decimalParts[0].Replace("-", "").
                             Replace("+", "").Length) + newNumber;

                result = result.TrimEnd('0');
            }
            float temp = 0.00F;

            if (float.TryParse(result, out temp))
            {
                return result;
            }
            throw new  Exception();
        }

        private static string GetZeros(int zeroCount)
        {
            if (zeroCount < 0)
                zeroCount = Math.Abs(zeroCount);

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < zeroCount; i++) sb.Append("0");

            return sb.ToString();
        }

        static void Main(string[] args)
        {
            //Get Input Directory.
            Console.WriteLine(@"Enter the Input Directory");
            var readLine = Console.ReadLine();
            if (readLine == null)
            {
                Console.WriteLine(@"Enter the input path properly.");
                return;
            }
            var pathToInputDirectory = readLine.Trim();

            //Get Output Directory.
            Console.WriteLine(@"Enter the Output Directory");
            readLine = Console.ReadLine();
            if (readLine == null)
            {
                Console.WriteLine(@"Enter the output path properly.");
                return;
            }
            var pathToOutputDirectory = readLine.Trim();

            //Get Delimiter.
            Console.WriteLine("Enter the delimiter;");
            var columnDelimiter = (char) Console.Read();

            //Loop over all files in the directory.
            foreach (var inputFileName in Directory.GetFiles(pathToInputDirectory))
            {
                var outputFileWithouthNumbersInScientificNotation = string.Empty;
                Console.WriteLine("Started operation on File : " + inputFileName);

                if (File.Exists(inputFileName))
                {
                    // Read the file
                    using (var file = new StreamReader(inputFileName))
                    {
                        string line;
                        while ((line = file.ReadLine()) != null)
                        {
                            String[] columns = line.Split(columnDelimiter);
                            var duplicateLine = string.Empty;
                            int lengthOfColumns = columns.Length;
                            int counter = 1;
                            foreach (var column in columns)
                            {
                                var columnDuplicate = column;
                                try
                                {
                                    if (Regex.IsMatch(columnDuplicate.Trim(),
                                                      @"^[+-]?[0-9]+(\.[0-9]+)?[E]([+-]?[0-9]+)$",
                                                      RegexOptions.IgnoreCase))
                                    {
                                        Console.WriteLine("Regular expression matched for this :" + column);

                                        columnDuplicate = ToLongString(Double.Parse
                                                                           (column,
                                                                            System.Globalization.NumberStyles.Float));

                                        Console.WriteLine("Converted this no in scientific notation " +
                                                          "" + column + "  to this number " +
                                                          columnDuplicate);
                                    }
                                }
                                catch (Exception)
                                {

                                }
                                duplicateLine = duplicateLine + columnDuplicate;

                                if (counter != lengthOfColumns)
                                {
                                    duplicateLine = duplicateLine + columnDelimiter.ToString();
                                }
                                counter++;
                            }
                            duplicateLine = duplicateLine + Environment.NewLine;
                            outputFileWithouthNumbersInScientificNotation = outputFileWithouthNumbersInScientificNotation + duplicateLine;
                        }

                        file.Close();
                    }

                    var outputFilePathWithoutNumbersInScientificNotation
                        = Path.Combine(pathToOutputDirectory, Path.GetFileName(inputFileName));

                    //Create the directory if it does not exist.
                    if (!Directory.Exists(pathToOutputDirectory))
                        Directory.CreateDirectory(pathToOutputDirectory);

                    using (var outputFile =
                        new StreamWriter(outputFilePathWithoutNumbersInScientificNotation))
                    {
                        outputFile.Write(outputFileWithouthNumbersInScientificNotation);
                        outputFile.Close();
                    }

                    Console.WriteLine("The transformed file is here :" +
                        outputFilePathWithoutNumbersInScientificNotation);
                }
            }
        }
    }
}

对于我们无法在MS Excel中打开的大文件,这种方法非常有效。

答案 1 :(得分:0)

谢谢彼得。 我将您的原创作品更新为: 1)接受输入文件或路径 2)每读取1000行后才写出处理语句 3)在处理过程中将变换后的行写入输出文件,这样就不会有大的字符串 4)在最后添加一个读取密钥,以便控制台在调试时不会自动退出

    using System;
using System.Text.RegularExpressions;
using System.IO;
using System.Text;
using System.Threading;

namespace ConvertScientificToLong
{
    class Program
    {
        private static string ToLongString(double input)
        {
            string str = input.ToString().ToUpper();

            // If string representation was collapsed from scientific notation, just return it:
            if (!str.Contains("E"))
                return str;

            var positive = true;
            if (input < 0)
            {
                positive = false;
            }

            string sep = Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator;
            char decSeparator = sep.ToCharArray()[0];

            string[] exponentParts = str.Split('E');
            string[] decimalParts = exponentParts[0].Split(decSeparator);

            // Fix missing decimal point:
            if (decimalParts.Length == 1)
                decimalParts = new string[] { exponentParts[0], "0" };

            int exponentValue = int.Parse(exponentParts[1]);

            string newNumber = decimalParts[0].Replace("-", "").
                Replace("+", "") + decimalParts[1];

            string result;

            if (exponentValue > 0)
            {
                if (positive)
                    result =
                       newNumber +
                       GetZeros(exponentValue - decimalParts[1].Length);
                else
                    result = "-" +
                     newNumber +
                     GetZeros(exponentValue - decimalParts[1].Length);


            }
            else // Negative exponent
            {
                if (positive)
                    result =
                        "0" +
                        decSeparator +
                        GetZeros(exponentValue + decimalParts[0].Replace("-", "").
                                   Replace("+", "").Length) + newNumber;
                else
                    result =
                    "-0" +
                    decSeparator +
                    GetZeros(exponentValue + decimalParts[0].Replace("-", "").
                             Replace("+", "").Length) + newNumber;

                result = result.TrimEnd('0');
            }
            float temp = 0.00F;

            if (float.TryParse(result, out temp))
            {
                return result;
            }
            throw new Exception();
        }

        private static string GetZeros(int zeroCount)
        {
            if (zeroCount < 0)
                zeroCount = Math.Abs(zeroCount);

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < zeroCount; i++) sb.Append("0");

            return sb.ToString();
        }

        static void Main(string[] args)
        {
            //Get Input Directory.
            Console.WriteLine(@"Enter the Input Directory or File Path");
            var readLine = Console.ReadLine();
            if (readLine == null)
            {
                Console.WriteLine(@"Enter the input path properly.");
                return;
            }
            var pathToInputDirectory = readLine.Trim();

            //Get Output Directory.
            Console.WriteLine(@"Enter the Output Directory");
            readLine = Console.ReadLine();
            if (readLine == null)
            {
                Console.WriteLine(@"Enter the output path properly.");
                return;
            }
            var pathToOutputDirectory = readLine.Trim();

            //Get Delimiter.
            Console.WriteLine("Enter the delimiter;");
            var columnDelimiter = (char)Console.Read();

            string[] inputFiles = null;

            if (File.Exists(pathToInputDirectory))
            {
                inputFiles = new String[]{pathToInputDirectory};
            }
            else
            {
                inputFiles = Directory.GetFiles(pathToInputDirectory);
            }

            //Loop over all files in the directory.
            foreach (var inputFileName in inputFiles)
            {
                var outputFileWithouthNumbersInScientificNotation = string.Empty;
                Console.WriteLine("Started operation on File : " + inputFileName);

                if (File.Exists(inputFileName))
                {
                    string outputFilePathWithoutNumbersInScientificNotation
                        = Path.Combine(pathToOutputDirectory, Path.GetFileName(inputFileName));

                    //Create the directory if it does not exist.
                    if (!Directory.Exists(pathToOutputDirectory))
                        Directory.CreateDirectory(pathToOutputDirectory);

                    using (var outputFile =
                        new StreamWriter(outputFilePathWithoutNumbersInScientificNotation))
                    {
                        // Read the file
                        using (StreamReader file = new StreamReader(inputFileName))
                        {
                            string line;
                            int lineCount = 0;
                            while ((line = file.ReadLine()) != null)
                            {
                                String[] columns = line.Split(columnDelimiter);
                                var duplicateLine = string.Empty;
                                int lengthOfColumns = columns.Length;
                                int counter = 1;
                                foreach (var column in columns)
                                {
                                    var columnDuplicate = column;
                                    try
                                    {
                                        if (Regex.IsMatch(columnDuplicate.Trim(),
                                                          @"^[+-]?[0-9]+(\.[0-9]+)?[E]([+-]?[0-9]+)$",
                                                          RegexOptions.IgnoreCase))
                                        {
                                            //Console.WriteLine("Regular expression matched for this :" + column);

                                            columnDuplicate = ToLongString(Double.Parse
                                                                               (column,
                                                                                System.Globalization.NumberStyles.Float));

                                            //Console.WriteLine("Converted this no in scientific notation " +
                                            //                  "" + column + "  to this number " +
                                            //                  columnDuplicate);

                                            if (lineCount % 1000 == 0)
                                            {
                                                Console.WriteLine(string.Format("processed {0} lines. still going....", lineCount));
                                            }
                                        }
                                    }
                                    catch (Exception)
                                    {

                                    }
                                    duplicateLine = duplicateLine + columnDuplicate;

                                    if (counter != lengthOfColumns)
                                    {
                                        duplicateLine = duplicateLine + columnDelimiter.ToString();
                                    }
                                    counter++;
                                }

                                outputFile.WriteLine(duplicateLine);

                                lineCount++;
                            }
                        }
                    }
                    Console.WriteLine("The transformed file is here :" +
                        outputFilePathWithoutNumbersInScientificNotation);

                    Console.WriteLine(@"Hit any key to exit");
                    Console.ReadKey();
                }
            }
        }
    }
}

答案 2 :(得分:0)

更简单的方法是将其另存为.csv文件。然后,而不是只打开文件 - 您转到数据选项卡并选择“从文本”,以便您可以获得对话框。这样,您可以使用科学记数法将该列标识为文本以消除该格式。导入文件,然后您可以将其重新格式化为数字或任何您想要的。