블로그 이미지
Every unexpected event is a path to learning for you.

카테고리

분류 전체보기 (2318)N
Unity3D (567)N
Programming (471)
Unreal (4)
Gamebryo (56)
Tip & Tech (183)
협업 (34)
3DS Max (3)
Game (12)
Utility (116)
Etc (92)
Link (31)
Portfolio (19)
Subject (90)
iOS,OSX (38)
Android (13)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (1)
Memories (19)
Interest (37)
Thinking (36)
한글 (26)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (19)
Exercise (3)
나만의 맛집 (2)
냥이 (9)
육아 (7)
Total1,339,007
Today20
Yesterday214
Statistics Graph

달력

« » 2019.11
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

공지사항

태그목록

C# Keywords

Programming/C# / 2014.05.13 15:37

출처 : http://msdn.microsoft.com/en-us/library/x53a06bb.aspx


C# Keywords

Visual Studio 2013
14 out of 17 rated this helpful Rate this topic

Keywords are predefined, reserved identifiers that have special meanings to the compiler. They cannot be used as identifiers in your program unless they include @ as a prefix. For example, @if is a valid identifier but if is not because if is a keyword.

The first table in this topic lists keywords that are reserved identifiers in any part of a C# program. The second table in this topic lists the contextual keywords in C#. Contextual keywords have special meaning only in a limited program context and can be used as identifiers outside that context. Generally, as new keywords are added to the C# language, they are added as contextual keywords in order to avoid breaking programs written in earlier versions.

Contextual Keywords

A contextual keyword is used to provide a specific meaning in the code, but it is not a reserved word in C#. Some contextual keywords, such as partial and where, have special meanings in two or more contexts.



'Programming > C#' 카테고리의 다른 글

NTP 서버에서 시간 가져오기(SNTP)  (0) 2014.07.14
C# 외부 프로그램 종료하기  (0) 2014.05.20
C# Keywords  (0) 2014.05.13
Standard Numeric Format Strings  (0) 2014.05.13
숫자 3자리마다 콤마(,) 찍기  (0) 2014.05.13
플래그 데이터와 이진 연산  (0) 2014.04.04
Posted by blueasa

댓글을 달아 주세요

Standard Numeric Format Strings

.NET Framework 4.5
37 out of 50 rated this helpful Rate this topic

Standard numeric format strings are used to format common numeric types. A standard numeric format string takes the form Axx, where A is an alphabetic character called the format specifier, and xx is an optional integer called the precision specifier. The precision specifier ranges from 0 to 99 and affects the number of digits in the result. Any numeric format string that contains more than one alphabetic character, including white space, is interpreted as a custom numeric format string. For more information, see Custom Numeric Format Strings.

Important note Important

The precision specifier controls the number of digits in the string representation of a number. It does not round the number itself. To perform a rounding operation, use the Math.CeilingMath.Floor, orMath.Round method.

Standard numeric format strings are supported by some overloads of the ToString method of all numeric types. For example, you can supply a numeric format string to the ToString(String) andToString(String, IFormatProvider) methods of the Int32 type. Standard numeric format strings are also supported by the .NET Framework composite formatting feature, which is used by some Write andWriteLine methods of the Console and StreamWriter classes, the String.Format method, and theStringBuilder.AppendFormat method.

Tip Tip

You can download the Format Utility, an application that enables you to apply format strings to either numeric or date and time values and displays the result string.

The following table describes the standard numeric format specifiers and displays sample output produced by each format specifier. See the Notes section for additional information about using standard numeric format strings, and the Example section for a comprehensive illustration of their use.

Format specifier

Name

Description

Examples

"C" or "c"

Currency

Result: A currency value.

Supported by: All numeric types.

Precision specifier: Number of decimal digits.

Default precision specifier: Defined bySystem.Globalization.NumberFormatInfo.

More information: The Currency ("C") Format Specifier.

123.456 ("C", en-US) -> $123.46

123.456 ("C", fr-FR) -> 123,46 €

123.456 ("C", ja-JP) -> ¥123

-123.456 ("C3", en-US) -> ($123.456)

-123.456 ("C3", fr-FR) -> -123,456 €

-123.456 ("C3", ja-JP) -> -¥123.456

"D" or "d"

Decimal

Result: Integer digits with optional negative sign.

Supported by: Integral types only.

Precision specifier: Minimum number of digits.

Default precision specifier: Minimum number of digits required.

More information: The Decimal("D") Format Specifier.

1234 ("D") -> 1234

-1234 ("D6") -> -001234

"E" or "e"

Exponential (scientific)

Result: Exponential notation.

Supported by: All numeric types.

Precision specifier: Number of decimal digits.

Default precision specifier: 6.

More information: The Exponential ("E") Format Specifier.

1052.0329112756 ("E", en-US) -> 1.052033E+003

1052.0329112756 ("e", fr-FR) -> 1,052033e+003

-1052.0329112756 ("e2", en-US) -> -1.05e+003

-1052.0329112756 ("E2", fr_FR) -> -1,05E+003

"F" or "f"

Fixed-point

Result: Integral and decimal digits with optional negative sign.

Supported by: All numeric types.

Precision specifier: Number of decimal digits.

Default precision specifier: Defined bySystem.Globalization.NumberFormatInfo.

More information: The Fixed-Point ("F") Format Specifier.

1234.567 ("F", en-US) -> 1234.57

1234.567 ("F", de-DE) -> 1234,57

1234 ("F1", en-US) -> 1234.0

1234 ("F1", de-DE) -> 1234,0

-1234.56 ("F4", en-US) -> -1234.5600

-1234.56 ("F4", de-DE) -> -1234,5600

"G" or "g"

General

Result: The most compact of either fixed-point or scientific notation.

Supported by: All numeric types.

Precision specifier: Number of significant digits.

Default precision specifier: Depends on numeric type.

More information: The General ("G") Format Specifier.

-123.456 ("G", en-US) -> -123.456

123.456 ("G", sv-SE) -> -123,456

123.4546 ("G4", en-US) -> 123.5

123.4546 ("G4", sv-SE) -> 123,5

-1.234567890e-25 ("G", en-US) -> -1.23456789E-25

-1.234567890e-25 ("G", sv-SE) -> -1,23456789E-25

"N" or "n"

Number

Result: Integral and decimal digits, group separators, and a decimal separator with optional negative sign.

Supported by: All numeric types.

Precision specifier: Desired number of decimal places.

Default precision specifier: Defined bySystem.Globalization.NumberFormatInfo.

More information: The Numeric ("N") Format Specifier.

1234.567 ("N", en-US) -> 1,234.57

1234.567 ("N", ru-RU) -> 1 234,57

1234 ("N1", en-US) -> 1,234.0

1234 ("N1", ru-RU) -> 1 234,0

-1234.56 ("N3", en-US) -> -1,234.560

-1234.56 ("N3", ru-RU) -> -1 234,560

"P" or "p"

Percent

Result: Number multiplied by 100 and displayed with a percent symbol.

Supported by: All numeric types.

Precision specifier: Desired number of decimal places.

Default precision specifier: Defined bySystem.Globalization.NumberFormatInfo.

More information: The Percent ("P") Format Specifier.

1 ("P", en-US) -> 100.00 %

1 ("P", fr-FR) -> 100,00 %

-0.39678 ("P1", en-US) -> -39.7 %

-0.39678 ("P1", fr-FR) -> -39,7 %

"R" or "r"

Round-trip

Result: A string that can round-trip to an identical number.

Supported by: SingleDouble, and BigInteger.

Precision specifier: Ignored.

More information: The Round-trip ("R") Format Specifier.

123456789.12345678 ("R") -> 123456789.12345678

-1234567890.12345678 ("R") -> -1234567890.1234567

"X" or "x"

Hexadecimal

Result: A hexadecimal string.

Supported by: Integral types only.

Precision specifier: Number of digits in the result string.

More information: The HexaDecimal ("X") Format Specifier.

255 ("X") -> FF

-1 ("x") -> ff

255 ("x4") -> 00ff

-1 ("X4") -> 00FF

Any other single character

Unknown specifier

Result: Throws a FormatException at run time.

Using Standard Numeric Format Strings

A standard numeric format string can be used to define the formatting of a numeric value in one of two ways:

  • It can be passed to an overload of the ToString method that has a format parameter. The following example formats a numeric value as a currency string in the current (in this case, the en-US) culture.

    decimal value = 123.456m;
    Console.WriteLine(value.ToString("C2"));
    // Displays $123.46
    
  • It can be supplied as the formatString parameter in a format item used with such methods asString.FormatConsole.WriteLine, and StringBuilder.AppendFormat. For more information, seeComposite Formatting. The following example uses a format item to insert a currency value in a string.

    decimal value = 123.456m;
    Console.WriteLine("Your account balance is {0:C2}.", value);
    // Displays "Your account balance is $123.46."
    

The following sections provide detailed information about each of the standard numeric format strings.

The Currency ("C") Format Specifier

The "C" (or currency) format specifier converts a number to a string that represents a currency amount. The precision specifier indicates the desired number of decimal places in the result string. If the precision specifier is omitted, the default precision is defined by theNumberFormatInfo.CurrencyDecimalDigits property.

If the value to be formatted has more than the specified or default number of decimal places, the fractional value is rounded in the result string. If the value to the right of the number of specified decimal places is 5 or greater, the last digit in the result string is rounded away from zero.

The result string is affected by the formatting information of the current NumberFormatInfo object. The following table lists the NumberFormatInfo properties that control the formatting of the returned string.

NumberFormatInfo property

Description

CurrencyPositivePattern

Defines the placement of the currency symbol for positive values.

CurrencyNegativePattern

Defines the placement of the currency symbol for negative values, and specifies whether the negative sign is represented by parentheses or the NegativeSign property.

NegativeSign

Defines the negative sign used if CurrencyNegativePattern indicates that parentheses are not used.

CurrencySymbol

Defines the currency symbol.

CurrencyDecimalDigits

Defines the default number of decimal digits in a currency value. This value can be overridden by using the precision specifier.

CurrencyDecimalSeparator

Defines the string that separates integral and decimal digits.

CurrencyGroupSeparator

Defines the string that separates groups of integral numbers.

CurrencyGroupSizes

Defines the number of integer digits that appear in a group.

The following example formats a Double value with the currency format specifier.

double value = 12345.6789;
Console.WriteLine(value.ToString("C", CultureInfo.CurrentCulture));

Console.WriteLine(value.ToString("C3", CultureInfo.CurrentCulture));

Console.WriteLine(value.ToString("C3", 
                  CultureInfo.CreateSpecificCulture("da-DK")));
// The example displays the following output on a system whose 
// current culture is English (United States): 
//       $12,345.68 
//       $12,345.679 
//       kr 12.345,679

Back to table

The Decimal ("D") Format Specifier

The "D" (or decimal) format specifier converts a number to a string of decimal digits (0-9), prefixed by a minus sign if the number is negative. This format is supported only for integral types.

The precision specifier indicates the minimum number of digits desired in the resulting string. If required, the number is padded with zeros to its left to produce the number of digits given by the precision specifier. If no precision specifier is specified, the default is the minimum value required to represent the integer without leading zeros.

The result string is affected by the formatting information of the current NumberFormatInfo object. As the following table shows, a single property affects the formatting of the result string.

NumberFormatInfo property

Description

NegativeSign

Defines the string that indicates that a number is negative.

The following example formats an Int32 value with the decimal format specifier.

int value; 

value = 12345;
Console.WriteLine(value.ToString("D"));
// Displays 12345
Console.WriteLine(value.ToString("D8"));
// Displays 00012345 

value = -12345;
Console.WriteLine(value.ToString("D"));
// Displays -12345
Console.WriteLine(value.ToString("D8"));
// Displays -00012345

Back to table

The Exponential ("E") Format Specifier

The exponential ("E") format specifier converts a number to a string of the form "-d.ddd…E+ddd" or "-d.ddd…e+ddd", where each "d" indicates a digit (0-9). The string starts with a minus sign if the number is negative. Exactly one digit always precedes the decimal point.

The precision specifier indicates the desired number of digits after the decimal point. If the precision specifier is omitted, a default of six digits after the decimal point is used.

The case of the format specifier indicates whether to prefix the exponent with an "E" or an "e". The exponent always consists of a plus or minus sign and a minimum of three digits. The exponent is padded with zeros to meet this minimum, if required.

The result string is affected by the formatting information of the current NumberFormatInfo object. The following table lists the NumberFormatInfo properties that control the formatting of the returned string.

NumberFormatInfo property

Description

NegativeSign

Defines the string that indicates that a number is negative for both the coefficient and exponent.

NumberDecimalSeparator

Defines the string that separates the integral digit from decimal digits in the coefficient.

PositiveSign

Defines the string that indicates that an exponent is positive.

The following example formats a Double value with the exponential format specifier.

double value = 12345.6789;
Console.WriteLine(value.ToString("E", CultureInfo.InvariantCulture));
// Displays 1.234568E+004

Console.WriteLine(value.ToString("E10", CultureInfo.InvariantCulture));
// Displays 1.2345678900E+004

Console.WriteLine(value.ToString("e4", CultureInfo.InvariantCulture));
// Displays 1.2346e+004

Console.WriteLine(value.ToString("E", 
                  CultureInfo.CreateSpecificCulture("fr-FR")));
// Displays 1,234568E+004

Back to table

The Fixed-Point ("F") Format Specifier

The fixed-point ("F) format specifier converts a number to a string of the form "-ddd.ddd…" where each "d" indicates a digit (0-9). The string starts with a minus sign if the number is negative.

The precision specifier indicates the desired number of decimal places. If the precision specifier is omitted, the current NumberFormatInfo.NumberDecimalDigits property supplies the numeric precision.

The result string is affected by the formatting information of the current NumberFormatInfo object. The following table lists the properties of the NumberFormatInfo object that control the formatting of the result string.

NumberFormatInfo property

Description

NegativeSign

Defines the string that indicates that a number is negative.

NumberDecimalSeparator

Defines the string that separates integral digits from decimal digits.

NumberDecimalDigits

Defines the default number of decimal digits. This value can be overridden by using the precision specifier.

The following example formats a Double and an Int32 value with the fixed-point format specifier.

int integerNumber;
integerNumber = 17843;
Console.WriteLine(integerNumber.ToString("F", 
                  CultureInfo.InvariantCulture));
// Displays 17843.00

integerNumber = -29541;
Console.WriteLine(integerNumber.ToString("F3", 
                  CultureInfo.InvariantCulture));
// Displays -29541.000 

double doubleNumber;
doubleNumber = 18934.1879;
Console.WriteLine(doubleNumber.ToString("F", CultureInfo.InvariantCulture));
// Displays 18934.19

Console.WriteLine(doubleNumber.ToString("F0", CultureInfo.InvariantCulture));
// Displays 18934

doubleNumber = -1898300.1987;
Console.WriteLine(doubleNumber.ToString("F1", CultureInfo.InvariantCulture));  
// Displays -1898300.2

Console.WriteLine(doubleNumber.ToString("F3", 
                  CultureInfo.CreateSpecificCulture("es-ES")));
// Displays -1898300,199                        

Back to table

The General ("G") Format Specifier

The general ("G") format specifier converts a number to the most compact of either fixed-point or scientific notation, depending on the type of the number and whether a precision specifier is present. The precision specifier defines the maximum number of significant digits that can appear in the result string. If the precision specifier is omitted or zero, the type of the number determines the default precision, as indicated in the following table.

Numeric type

Default precision

Byte or SByte

3 digits

Int16 or UInt16

5 digits

Int32 or UInt32

10 digits

Int64

19 digits

UInt64

20 digits

BigInteger

50 digits

Single

7 digits

Double

15 digits

Decimal

29 digits

Fixed-point notation is used if the exponent that would result from expressing the number in scientific notation is greater than -5 and less than the precision specifier; otherwise, scientific notation is used. The result contains a decimal point if required, and trailing zeros after the decimal point are omitted. If the precision specifier is present and the number of significant digits in the result exceeds the specified precision, the excess trailing digits are removed by rounding.

However, if the number is a Decimal and the precision specifier is omitted, fixed-point notation is always used and trailing zeros are preserved.

If scientific notation is used, the exponent in the result is prefixed with "E" if the format specifier is "G", or "e" if the format specifier is "g". The exponent contains a minimum of two digits. This differs from the format for scientific notation that is produced by the exponential format specifier, which includes a minimum of three digits in the exponent.

The result string is affected by the formatting information of the current NumberFormatInfo object. The following table lists the NumberFormatInfo properties that control the formatting of the result string.

NumberFormatInfo property

Description

NegativeSign

Defines the string that indicates that a number is negative.

NumberDecimalSeparator

Defines the string that separates integral digits from decimal digits.

PositiveSign

Defines the string that indicates that an exponent is positive.

The following example formats assorted floating-point values with the general format specifier.

double number;

number = 12345.6789;      
Console.WriteLine(number.ToString("G", CultureInfo.InvariantCulture));
// Displays  12345.6789
Console.WriteLine(number.ToString("G", 
                  CultureInfo.CreateSpecificCulture("fr-FR")));
// Displays 12345,6789

Console.WriteLine(number.ToString("G7", CultureInfo.InvariantCulture));
// Displays 12345.68 

number = .0000023;
Console.WriteLine(number.ToString("G", CultureInfo.InvariantCulture));
// Displays 2.3E-06       
Console.WriteLine(number.ToString("G", 
                  CultureInfo.CreateSpecificCulture("fr-FR")));
// Displays 2,3E-06

number = .0023;
Console.WriteLine(number.ToString("G", CultureInfo.InvariantCulture));
// Displays 0.0023

number = 1234;
Console.WriteLine(number.ToString("G2", CultureInfo.InvariantCulture));
// Displays 1.2E+03

number = Math.PI;
Console.WriteLine(number.ToString("G5", CultureInfo.InvariantCulture));
// Displays 3.1416    

Back to table

The Numeric ("N") Format Specifier

The numeric ("N") format specifier converts a number to a string of the form "-d,ddd,ddd.ddd…", where "-" indicates a negative number symbol if required, "d" indicates a digit (0-9), "," indicates a group separator, and "." indicates a decimal point symbol. The precision specifier indicates the desired number of digits after the decimal point. If the precision specifier is omitted, the number of decimal places is defined by the current NumberFormatInfo.NumberDecimalDigits property.

The result string is affected by the formatting information of the current NumberFormatInfo object. The following table lists the NumberFormatInfo properties that control the formatting of the result string.

NumberFormatInfo property

Description

NegativeSign

Defines the string that indicates that a number is negative.

NumberNegativePattern

Defines the format of negative values, and specifies whether the negative sign is represented by parentheses or the NegativeSignproperty.

NumberGroupSizes

Defines the number of integral digits that appear between group separators.

NumberGroupSeparator

Defines the string that separates groups of integral numbers.

NumberDecimalSeparator

Defines the string that separates integral and decimal digits.

NumberDecimalDigits

Defines the default number of decimal digits. This value can be overridden by using a precision specifier.

The following example formats assorted floating-point values with the number format specifier.

double dblValue = -12445.6789;
Console.WriteLine(dblValue.ToString("N", CultureInfo.InvariantCulture));
// Displays -12,445.68
Console.WriteLine(dblValue.ToString("N1", 
                  CultureInfo.CreateSpecificCulture("sv-SE")));
// Displays -12 445,7 

int intValue = 123456789;
Console.WriteLine(intValue.ToString("N1", CultureInfo.InvariantCulture));
// Displays 123,456,789.0 

Back to table

The Percent ("P") Format Specifier

The percent ("P") format specifier multiplies a number by 100 and converts it to a string that represents a percentage. The precision specifier indicates the desired number of decimal places. If the precision specifier is omitted, the default numeric precision supplied by the currentPercentDecimalDigits property is used.

The following table lists the NumberFormatInfo properties that control the formatting of the returned string.

NumberFormatInfo property

Description

PercentPositivePattern

Defines the placement of the percent symbol for positive values.

PercentNegativePattern

Defines the placement of the percent symbol and the negative symbol for negative values.

NegativeSign

Defines the string that indicates that a number is negative.

PercentSymbol

Defines the percent symbol.

PercentDecimalDigits

Defines the default number of decimal digits in a percentage value. This value can be overridden by using the precision specifier.

PercentDecimalSeparator

Defines the string that separates integral and decimal digits.

PercentGroupSeparator

Defines the string that separates groups of integral numbers.

PercentGroupSizes

Defines the number of integer digits that appear in a group.

The following example formats floating-point values with the percent format specifier.

double number = .2468013;
Console.WriteLine(number.ToString("P", CultureInfo.InvariantCulture));
// Displays 24.68 %
Console.WriteLine(number.ToString("P", 
                  CultureInfo.CreateSpecificCulture("hr-HR")));
// Displays 24,68%     
Console.WriteLine(number.ToString("P1", CultureInfo.InvariantCulture));
// Displays 24.7 %

Back to table

The Round-trip ("R") Format Specifier

The round-trip ("R") format specifier guarantees that a numeric value that is converted to a string will be parsed back into the same numeric value. This format is supported only for the SingleDouble, and BigInteger types.

When a BigInteger value is formatted using this specifier, its string representation contains all the significant digits in the BigInteger value. When a Single or Double value is formatted using this specifier, it is first tested using the general format, with 15 digits of precision for a Double and 7 digits of precision for a Single. If the value is successfully parsed back to the same numeric value, it is formatted using the general format specifier. If the value is not successfully parsed back to the same numeric value, it is formatted using 17 digits of precision for a Double and 9 digits of precision for aSingle.

Although you can include a precision specifier, it is ignored. Round trips are given precedence over precision when using this specifier.

The result string is affected by the formatting information of the current NumberFormatInfo object. The following table lists the NumberFormatInfo properties that control the formatting of the result string.

NumberFormatInfo property

Description

NegativeSign

Defines the string that indicates that a number is negative.

NumberDecimalSeparator

Defines the string that separates integral digits from decimal digits.

PositiveSign

Defines the string that indicates that an exponent is positive.

The following example formats Double values with the round-trip format specifier.

double value;

value = Math.PI;
Console.WriteLine(value.ToString("r"));
// Displays 3.1415926535897931
Console.WriteLine(value.ToString("r", 
                  CultureInfo.CreateSpecificCulture("fr-FR")));
// Displays 3,1415926535897931 
value = 1.623e-21;
Console.WriteLine(value.ToString("r"));
// Displays 1.623E-21

Back to table

The Hexadecimal ("X") Format Specifier

The hexadecimal ("X") format specifier converts a number to a string of hexadecimal digits. The case of the format specifier indicates whether to use uppercase or lowercase characters for hexadecimal digits that are greater than 9. For example, use "X" to produce "ABCDEF", and "x" to produce "abcdef". This format is supported only for integral types.

The precision specifier indicates the minimum number of digits desired in the resulting string. If required, the number is padded with zeros to its left to produce the number of digits given by the precision specifier.

The result string is not affected by the formatting information of the current NumberFormatInfoobject.

The following example formats Int32 values with the hexadecimal format specifier.

int value; 

value = 0x2045e;
Console.WriteLine(value.ToString("x"));
// Displays 2045e
Console.WriteLine(value.ToString("X"));
// Displays 2045E
Console.WriteLine(value.ToString("X8"));
// Displays 0002045E 

value = 123456789;
Console.WriteLine(value.ToString("X"));
// Displays 75BCD15
Console.WriteLine(value.ToString("X2"));
// Displays 75BCD15

Back to table

Notes

Control Panel Settings

The settings in the Regional and Language Options item in Control Panel influence the result string produced by a formatting operation. Those settings are used to initialize theNumberFormatInfo object associated with the current thread culture, which provides values used to govern formatting. Computers that use different settings generate different result strings.

In addition, if the CultureInfo.CultureInfo(String) constructor is used to instantiate a new CultureInfoobject that represents the same culture as the current system culture, any customizations established by the Regional and Language Options item in Control Panel will be applied to the new CultureInfo object. You can use the CultureInfo.CultureInfo(String, Boolean) constructor to create a CultureInfo object that does not reflect a system's customizations.

NumberFormatInfo Properties

Formatting is influenced by the properties of the current NumberFormatInfo object, which is provided implicitly by the current thread culture or explicitly by the IFormatProvider parameter of the method that invokes formatting. Specify a NumberFormatInfo or CultureInfo object for that parameter.

Note Note

For information about customizing the patterns or strings used in formatting numeric values, see the NumberFormatInfo class topic.

Integral and Floating-Point Numeric Types

Some descriptions of standard numeric format specifiers refer to integral or floating-point numeric types. The integral numeric types are ByteSByteInt16Int32Int64UInt16UInt32UInt64, andBigInteger. The floating-point numeric types are DecimalSingle, and Double.

Floating-Point Infinities and NaN

Regardless of the format string, if the value of a Single or Double floating-point type is positive infinity, negative infinity, or not a number (NaN), the formatted string is the value of the respectivePositiveInfinitySymbolNegativeInfinitySymbol, or NaNSymbol property that is specified by the currently applicable NumberFormatInfo object.

Example

The following example formats an integral and a floating-point numeric value using the en-US culture and all the standard numeric format specifiers. This example uses two particular numeric types (Double and Int32), but would yield similar results for any of the other numeric base types (Byte,SByteInt16Int32Int64UInt16UInt32UInt64BigIntegerDecimal, and Single).

using System;
using System.Globalization;
using System.Threading;

public class NumericFormats
{
   public static void Main()
   {
      // Display string representations of numbers for en-us culture
      CultureInfo ci = new CultureInfo("en-us");

      // Output floating point values 
      double floating = 10761.937554;
      Console.WriteLine("C: {0}", 
              floating.ToString("C", ci));           // Displays "C: $10,761.94"
      Console.WriteLine("E: {0}", 
              floating.ToString("E03", ci));         // Displays "E: 1.076E+004"
      Console.WriteLine("F: {0}", 
              floating.ToString("F04", ci));         // Displays "F: 10761.9376"         
      Console.WriteLine("G: {0}",  
              floating.ToString("G", ci));           // Displays "G: 10761.937554"
      Console.WriteLine("N: {0}", 
              floating.ToString("N03", ci));         // Displays "N: 10,761.938"
      Console.WriteLine("P: {0}", 
              (floating/10000).ToString("P02", ci)); // Displays "P: 107.62 %"
      Console.WriteLine("R: {0}", 
              floating.ToString("R", ci));           // Displays "R: 10761.937554"            
      Console.WriteLine();

      // Output integral values 
      int integral = 8395;
      Console.WriteLine("C: {0}", 
              integral.ToString("C", ci));           // Displays "C: $8,395.00"
      Console.WriteLine("D: {0}", 
              integral.ToString("D6", ci));          // Displays "D: 008395" 
      Console.WriteLine("E: {0}", 
              integral.ToString("E03", ci));         // Displays "E: 8.395E+003"
      Console.WriteLine("F: {0}", 
              integral.ToString("F01", ci));         // Displays "F: 8395.0"    
      Console.WriteLine("G: {0}",  
              integral.ToString("G", ci));           // Displays "G: 8395"
      Console.WriteLine("N: {0}", 
              integral.ToString("N01", ci));         // Displays "N: 8,395.0"
      Console.WriteLine("P: {0}", 
              (integral/10000.0).ToString("P02", ci)); // Displays "P: 83.95 %"
      Console.WriteLine("X: 0x{0}", 
              integral.ToString("X", ci));           // Displays "X: 0x20CB"
      Console.WriteLine();
   }
}


출처 : http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx

'Programming > C#' 카테고리의 다른 글

C# 외부 프로그램 종료하기  (0) 2014.05.20
C# Keywords  (0) 2014.05.13
Standard Numeric Format Strings  (0) 2014.05.13
숫자 3자리마다 콤마(,) 찍기  (0) 2014.05.13
플래그 데이터와 이진 연산  (0) 2014.04.04
How to create Excel file in C#(Source)  (0) 2014.03.26
Posted by blueasa

댓글을 달아 주세요

1. int won = 123456890;

2. Console.WriteLine(string.Format("{0:n0}", won));

3. Console.WriteLine(string.Format("{0}", won.ToString("n0"))); ;

4. Console.WriteLine(string.Format("{0:#,##0}", won));

5. Console.WriteLine(string.Format("{0}", won.ToString("#,##0")));

6.

7. //결과

8. //123,456,890

9. //123,456,890

10. //123,456,890

11. //123,456,890


스트링에다 .ToString("n0")를 시전하고 있었다... - _ -;....

스트링은 인트로 파스해서 변환해야하나...



출처 : http://ericstoltz.tistory.com/147


참조 : Standard Numeric Format Strings

'Programming > C#' 카테고리의 다른 글

C# Keywords  (0) 2014.05.13
Standard Numeric Format Strings  (0) 2014.05.13
숫자 3자리마다 콤마(,) 찍기  (0) 2014.05.13
플래그 데이터와 이진 연산  (0) 2014.04.04
How to create Excel file in C#(Source)  (0) 2014.03.26
C# Excel Tutorial  (0) 2014.03.26
Posted by blueasa

댓글을 달아 주세요

개요

얼마 전 Justin Yoo님의 논리 연산자와 이진 연산자의 차이에 대한 블로그 포스트가 그 분의 의도와는 다르게 페이스북 ‘생활코딩’ 그룹에 콜로세움(?)을 세운 사건이 있었습니다. 저는 포함되지 않아서 아쉬운 내용이 조금 있었지만 많은 분들에게 도움이 될만한 글이며 크게 문제가 될 부분은 없다고 생각했는데 다른 의견을 가진 분들이 많이 있었습니다. 급기야 C#의 논리 연산자와 이진 연산자 내부 동작이 C/C++과 같지 않다는 오해까지 번져나갔습니다. C/C++에만 익숙한 분들이 겉모습이 비슷하긴 하지만 C#에서는 논리 연산자는 오직 System.Boolean 값 사이에만 사용 가능하며(연산자 사용자 정의는 논외로 하겠습니다. 일이 너무 커져요…) 조건식 결과 역시 System.Boolean 형식만 가능함을 알지 못했기 때문입니다. 마찬가지로 C#만 경험한 분들은 C/C++에서 if 구문과 조건부 삼항 연산자(?:)에 다양한 형식의 식이 사용된다는 점을 몰랐겠죠.

그리고 2주 쯤 전에 회사에서 코드 리뷰를 할 때 동료 사원 한 분이 플래그 열거형의 필드 값을 10진수가 아닌 16진수를 사용해 정의한 이유를 물어보셨는데 당시 시간 여건 상(점심시간이 다가오고 있었어요!) 충분한 설명을 해 드리지 못했습니다. 그래서 해당 내용과 Justin Yoo님의 포스트에 포함되지 않은 내용을 함께 정리해 봅니다. 언어는 C#을 기준으로 진행하지만 개념적인 부분은 다른 프로그래밍 언어에도 그대로 적용됩니다.

C#의 논리 연산자와 이진 연산자 내부 동작이 궁금하면 C++로 작성된 CLI 소스 코드를 확인하는 것을 권합니다.

이 글을 먼저 읽고 Justin Yoo님의 포스트를 읽으시면 더 이해가 쉬울 거라 생각됩니다.

1비트(bit) 데이터

Flags를 말 그대로 풀이하면 여러 개의 깃발입니다. 프로그래밍에서 깃발은 올려진 상태 또는 내려진 상태를 나타내는 데이터를 의미합니다. 다시 말해 0 또는 1, 참 또는 거짓, 예 또는 아니오 등의 상태를 표현하기 위해 사용됩니다. 서로 다른 두 개의 상태를 표현하기 위해 컴퓨터는 0 또는 1을 나타내는 한 개의 비트를 사용합니다. 일반적으로 컴퓨터가 데이터를 처리하는 최소 단위는 8개의 비트로 이루어진 바이트(byte)입니다. 그리고 매우 자주 사용되는 자료형인 System.Int32의 크기는 4바이트, 즉 32비트입니다. 32비트 공간에는 1개의 32비트 크기의(도메인에 정의되는) 정보를 저장할 수 있습니다. 16비트 크기의 정보는 2개를, 8비트 크기의 정보는 4개를 저장할 수 있지요. 마찬가지로 1비트 크기의 정보는 32개를 저장할 수 있습니다.

1
2
3
16 x  2 ++++ ++++  ++++ ++++  ---- ----  ---- ----
 8 x  4 ++++ ++++  ---- ----  ++++ ++++  ---- ----
 1 x 32 +-+- +-+-  +-+- +-+-  +-+- +-+-  +-+- +-+-

16진수

정수 데이터의 각 비트 값을 표현하는 데에는 10진수보다는 16진수가 더 다루기 쉽습니다. 이유를 설명하기 전에 16비트 데이터의 모든 비트 값을 10진수와 16진수로 나타낸 표를 먼저 확인하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
                        Dec     Hex
------------------- ------- -------
0000 0000 0000 0001       1  0x0001
0000 0000 0000 0010       2  0x0002
0000 0000 0000 0100       4  0x0004
0000 0000 0000 1000       8  0x0008
 
0000 0000 0001 0000      16  0x0010
0000 0000 0010 0000      32  0x0020
0000 0000 0100 0000      64  0x0040
0000 0000 1000 0000     128  0x0080
 
0000 0001 0000 0000     256  0x0100
0000 0010 0000 0000     512  0x0200
0000 0100 0000 0000    1024  0x0400
0000 1000 0000 0000    2048  0x0800
 
0001 0000 0000 0000    4096  0x1000
0010 0000 0000 0000    8198  0x2000
0100 0000 0000 0000   16384  0x4000
1000 0000 0000 0000   32768  0x8000

10진수의 경우에는 별다른 패턴이 없지만 16진수는 4개 비트 마다 1, 2, 4, 8이 자릿수가 변경되며 반복되는 것을 볼 수 있습니다. 8진수를 사용해도 1, 2, 4가 반복되지만 3개 비트 단위로 반복되는 것보다 4개 단위로 반복되는 것이 8비트, 16비트, 32비트, 64비트 데이터를 표현하기에 좀 더 편리합니다. 그래서 4비트가 넘어가는 플래그 데이터를 정의할 때 16진수가 주로 사용됩니다.

이진 연산

플래그 데이터를 다룰 때에는 산술 연산이 아닌 이진 연산을 사용합니다. 이진 연산을 이용해 플래그를 조합하거나 제거하고 데이터에 특정 플래그가 포함되어 있는지 검사합니다.

이진 OR 연산

플래그 데이터를 조합하는 데에 이진 | 연산자를 사용합니다. 이진 OR 연산은 두 개의 데이터에 대해 각 비트 별로 논리합 연산을 수행합니다. 두 비트 중 하나 이상의 값이 1이면 결과 비트는 1이고 두 비트 모두 0이면 결과 비트는 0입니다. 이진 OR 연산을 사용해 어떻게 플래그 데이터를 조합하는지 살펴봅니다.

1
2
3
4
5
6
7
8
var a = 1;     // 1(0001)
var b = 2;     // 2(0010)
 
var c = a | b; // 3(0011)
var d = a + b; // 3(0011)
 
var e = a | c; // 3(0011)
var f = a + c; // 4(0100)

위 코드를 보면 a와 b는 중복되는 비트가 없는데 이런 경우는 | 연산 결과는 + 연산 결과와 같습니다. 그래서 c와 d는 값이 같습니다. 하지만 중복되는 비트가 있으면 두 연산 결과는 같지 않습니다. e의 경우 a가 가진 비트 값과 c가 가진 비트 값이 모두 유지되어 있지만 f는 두 개의 비트가 사라지고 하나의 비트가 생겼났습니다.

이진 AND 연산

데이터에 특정 플래그가 포함되어 있는지 검사하는 데에 & 연산자를 사용합니다. 이진 AND 연산은 두 개의 데이터를 각 비트 별로 논리곱 연산을 수행합니다. 두 비트 모두 1이면 결과 비트는 1이고 둘 중 하나 이상의 비트가 0이면 결과 비트는 0입니다. 이진 AND 연산을 사용해 플래그 포함 여부를 검사하는 방법을 살펴봅니다.

1
2
3
4
5
6
7
8
9
10
11
var a = 1;                // 1(0001)
var b = 2;                // 2(0010)
var c = 4;                // 4(0100)
 
var d = a | c;            // 5(0101)
 
var e = d & a;            // 1(0001)
var f = d & b;            // 0(0000)
 
bool hasA = (d & a) == a; // True
bool hasB = (d & b) == b; // False

abc는 서로 다른 비트 값을 가지는 플래그들이고 d는 a와 c의 조합입니다. 이 때 d가 특정 플래그를 포함하는지 여부를 알아보려면 대상 플래그와 논리곱 연산을 수행한 결과가 해당 플래그와 같은지 검사하면 됩니다.

이진 배타적 OR 연산

이진 배타적 OR 연산을 사용하면 데이터에서 특정 플래그를 제거할 수 있습니다. 이진 배타적 OR 연산은 두 개의 데이터에 대해 각 비트 별로 배타적 논리합 연산을 수행합니다. 두 비트의 값이 다르면 결과 비트는 1이고 두 비트의 값이 같으면 결과 비트는 0입니다. 아래 코드는 이진 배타적 OR 연산을 사용해 데이터에서 특정 플래그를 제거하는 방법을 보여줍니다.

1
2
3
4
5
6
7
var a = 1;           // 1(0001)
var b = 2;           // 2(0010)
var c = 4;           // 4(0100)
 
var d = a | b | c;   // 7(0111)
 
var e = (d ^ b) & d; // 5(0101)

d는 abc 플래그가 조합된 값입니다. d와 b의 이진 배타적 OR 연산을 수행한 결과와 d의 논리곱 연산을 수행하면 d에서 b 플래그를 제거한 값을 얻을 수 있습니다. 이때 주의할 것은 마지막 논리곱 연산을 빠뜨리면 안된다는 점입니다. 위 코드의 경우는 b가 가진 모든 비트를 d가 포함하고 있기 때문에 논리곱 연산 전후 값이 같지만 만약 d가 가지지 않은 비트를 가진 데이터(예를 들어 1010 비트를 가진 데이터)의 플래그들을 d에서 제거하려할 경우 논리곱 연산을 생략하면 잘못된 값을 얻게됩니다.

이진 보수 연산

이진 보수 연산을 사용해도 데이터에서 특정 플래그를 제거할 수 있습니다. 이진 보수 연산은 앞에 설명된 연산자들과는 달리 이항 연산이 아닌 단항 연산이며 각 비트에 대해 0은 1로, 1은 0으로 변환된 값을 반환합니다.

1
2
3
4
5
6
7
var a = 1;         // 1(0001)
var b = 2;         // 2(0010)
var c = 4;         // 4(0100)
 
var d = a | b | c; // 7(0111)
 
var e = (d & ~b);  // 5(0101)

이진 배타적 OR 연산의 예제와 동일한 작업을 하는 코드입니다. 제거하려는 플래그를 가진 데이터의 이진 보수 연산 결과와 논리곱 연산을 수행하면 원본 데이터에서 특정 플래그를 삭제할 수 있습니다. 이진 배타적 OR 연산을 사용한 플래그 제거와 결과는 동일하지만 성능은 조금 더 높습니다.

System.FlagsAttribute

.NET Framework 코드에서 플래그를 정의할 때 System.FlagsAttribute 특성을 가진 열거형(enum)을 사용합니다. System.FlagsAttribute 특성은 열거형의 멤버가 플래그 데이터 또는 플래그 데이터의 조합을 나타냄을 의미합니다. 이런 경우 하나의 변수에 여러 개의 이진 데이터를 담기 때문에 열거형의 이름은 주로 복수형 명사가 됩니다.

다음은 추적 출력 대상을 지정하는 System.Diagnostics.TraceOptions 열거형 정의입니다.

1
2
3
4
5
6
7
8
9
10
[Flags]
public enum TraceOptions {
    None                  =    0,
    LogicalOperationStack = 0x01,
    DateTime              = 0x02,
    Timestamp             = 0x04,
    ProcessId             = 0x08,
    ThreadId              = 0x10,
    Callstack             = 0x20,
}

System.FlagsAttribute 특성을 가진 열거형 멤버의 값이 반드시 하나의 비트 플래그만 가질 필요는 없습니다. 예를 들어 All = 0x3F와 같은 멤버를 추가로 정의할 수 있습니다. 또 이런 여러 플래그를 포함하는 멤버를 정의할 때 이미 정의된 멤버를 조합하는 것도 가능합니다.

1
2
3
4
5
6
[Flags]
public enum TraceOptions {
    ...
    All = LogicalOperationStack | DateTime | Timestamp |
          ProcessId | ThreadId | Callstack
}

이 열거형에 대해 플래그 조합하고, 포함 여부를 검사하고, 그리고 특정 플래그를 제거하는 예제입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
TraceOptions options = TraceOptions.DateTime;
 
Console.WriteLine(options); // DateTime
 
// Add ProcessId and Callstack
options |= (TraceOptions.ProcessId | TraceOptions.Callstack);
 
Console.WriteLine(options); // DateTime, ProcessId, Callstack
 
// Remove DateTime
options &= ~TraceOptions.DateTime;
 
Console.WriteLine(options); // ProcessId, Callstack
 
Console.WriteLine((options & TraceOptions.DateTime) == TraceOptions.DateTime); // False
Console.WriteLine(options.HasFlag(TraceOptions.ProcessId)); // True

위 코드의 마지막 줄에 사용된 HasFlag() 메서드는  .NET Framework 4.0에 등장한 메서드입니다. 논리곱 연산자를 사용한 플래그 검사와 비교할 때 성능이 낮은 반면 코드를 좀 더 직관적이고 간편하게 작성하도록 도와줍니다. 아래는 HasFlag() 메서드의 내부 구현입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[System.Security.SecuritySafeCritical]
public Boolean HasFlag(Enum flag) {
    if (flag == null)
        throw new ArgumentNullException("flag");
    Contract.EndContractBlock();
 
    if (!this.GetType().IsEquivalentTo(flag.GetType())) {
        throw new ArgumentException(Environment.GetResourceString("Argument_EnumTypeDoesNotMatch", flag.GetType(), this.GetType()));
    }
 
    return InternalHasFlag(flag);
}
 
[System.Security.SecurityCritical]
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool InternalHasFlag(Enum flags);

저는 플래그 검사가 짧은 시간에 반복적으로 아주 많이 수행되지 않는다면 HasFlag() 메서드를 사용해 가독성 높은 코드를 작성하는 편을 선호합니다.

결론

이진 연산을 이해하고 플래그 데이터를 적절히 사용하면 메모리 효율을 높이고 메서드 매개 변수를 줄여주는 등 간결한 코드 작성에 도움을 줍니다. 지금보다 메모리가 많이 귀하던(물론 지금도 귀하죠!) 시절에는 하나의 비트로 표현될 수 있는 여러 개의 데이터를 각각 정수형 변수에 저장하는 것은 더더욱 피해야 할 과소비였습니다.



Posted by blueasa

댓글을 달아 주세요

xls와 xlsx 둘 다 되도록 예제를 약간 수정해서 테스트 완료.


P.s. 무슨 이유인지 모르지만 VS2013에서는 Microsoft.Office.Interop.Excel 이 없어서, 부득이하게 VS2010으로 작업함.

       (VS2012는 있는지 확인은 안해봤지만.. 얼핏 인터넷에서 보기로는 VS2012도 없는 듯..)

        
        private void CreateExcelFile()
        {
            Excel.Application xlApp;
            Excel.Workbook xlWorkBook;
            Excel.Worksheet xlWorkSheet;
            object misValue = System.Reflection.Missing.Value;

            xlApp = new Excel.Application();
            // 생성할 때, 기본 Sheet 1개.
            xlWorkBook = xlApp.Workbooks.Add(misValue);

            // Sheet 추가.(필요한 Sheet 개수에 따라 루프 돌아야 될 듯)
            xlWorkBook.Worksheets.Add(misValue, misValue, misValue, misValue);

            xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
            // Sheet Name 지정.
            xlWorkSheet.Name = "SheetName1";
            xlWorkSheet.Cells[1, 1] = "http://csharp.net-informations.com";

            xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(2);
            xlWorkSheet.Name = "SheetName2";
            xlWorkSheet.Cells[1, 1] = "http://csharp.net-informations.com";

            // 테스트용으로 파일명 직접 입력.
            string createFilePath = Directory.GetCurrentDirectory() + @"\" + "csharp-Excel.xlsx";

            // 파일 있으면 삭제.
            if (true == File.Exists(createFilePath))
            {
                File.Delete(createFilePath);
            }

            // 확장자만 검사하기 위해..
            string strExtension = Path.GetExtension(createFilePath);

            if (0 == strExtension.CompareTo(".xlsx"))
            {
                xlWorkBook.SaveAs(createFilePath, Excel.XlFileFormat.xlOpenXMLWorkbook, misValue, misValue, false, false, Excel.XlSaveAsAccessMode.xlNoChange, Excel.XlSaveConflictResolution.xlUserResolution, true, misValue, misValue, misValue);
            }
            else if (0 == strExtension.CompareTo(".xls"))
            {
                xlWorkBook.SaveAs(createFilePath, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
            }

            xlWorkBook.Close(true, misValue, misValue);
            xlApp.Quit();

            releaseObject(xlWorkSheet);
            releaseObject(xlWorkBook);
            releaseObject(xlApp);

            MessageBox.Show("Excel file created , you can find the file " + createFilePath);
        }

        private void releaseObject(object obj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                obj = null;
            }
            catch (Exception ex)
            {
                obj = null;
                MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
            }
            finally
            {
                GC.Collect();
            }
        }



엑셀 생성 참조 : http://csharp.net-informations.com/excel/csharp-create-excel.htm

xlsx 참조 : http://stackoverflow.com/questions/9769703/exporting-to-xlsx-using-microsoft-office-interop-excel-saveas-error


Posted by blueasa
TAG Excel, xls, xlsx

댓글을 달아 주세요

C# Excel Tutorial

Programming/C# / 2014.03.26 15:02
 C# Excel Tutorial


Posted by blueasa
TAG Excel

댓글을 달아 주세요


[제작자 황현우님의 파일]

LiAsExcelDB.cs


[개인적으로 필요해서 소스 좀 수정된 파일]

LiAsExcelDB.cs




C# 에서 Excel 로 데이터 기록 및 읽기 [OleDB]

 

OleDB 를 이용한 Excel 로 데이터베이스 처럼이용하기 입니다만...

Excel 을 제어하는 방법으로 사용해도 무방합니다. 저장이.. 1만건 이상일 때부터는 좀 느려지지만

(제 PC 에서는 한 2초 정도 걸리는 군효..) 읽기는 순식간입니다.

대량으로 저장할 때는 다른 방식으로 해야될 듯..

 

[참고] 요기 본문에 나오는 모든 소스는 첨부된 파일에 있으니, 복사해서 쓰지 마시고..

그리고 퍼가시거나 소스를 사용하신다면 댓글이라도 남겨주시는 센스도.. 사실 퍼가면 코딩하는

시간 버는 거니.. 댓글 다시는데 약간의 시간의 사용하셔도 쿨럭..ㅡ.,ㅡ;;

 

흠,.. C# 에서는 좀 사기적인(?) 지원이 많은 관계로.. 엄청 편리하네요.. 속도는 좀 떨어지만서도..

여튼,.. 프로그램을 만들때.. 매번 DB 를 쓰기도 그렇고.. 그렇다고 Access 쓰기도 구차니즘에

손가락이 떨려오신다면.. Excel 파일을 DB 처럼 사용하는 방법을 이용하는 것도 나름 좋은

방법입니다. 일단 내용의 보안이나 등등의 기능까지 하긴 너무 양이 많아 질꺼 같고..

최대한 간단하게 Excel 파일을 제어해서 Database 처럼 사용하는 방법을 살펴보죠..

(검색해보시면 비슷자료가 많이 있으니 다른 사람들의 것도 참고 하시는 것도 좋은 공부방법이죠..)

 

먼저 Excel 의 구조와 C# 의 DataSet 을 간단하게 살펴보면... 왠지 느낌이 팍! 하고 오실껍니다.

 

DataSet : 테이블의 집합

Excel : Sheet 의 집합 -> 즉, 하나의 시트가 DataSet 에 하나의 Table 이라고 생각하면 됩니다.

 

DataTable : 하나의 테이블 객체.. 컬럼과 줄이 존재하지요..

Sheet : 열과 행이 존재하지요.. 테이블로 보자면 컬럼과 줄..

 

그렇습니다.. -_-;; 이넘들이 개념이 같은 넘들이였습니다. (원래도 같은 넘들이였죠.. DOS 시절에..)

 



 

위와 같이 되는 거죠.. sheet 명이 table 명,  첫번째 줄의 데이터가 Field 명이 됩니다.

음.. 개념 잡기는 여기까지만 하고.. 본격적인 내용으로 들어가면...

 

[ Excel 파일 버전 검사 ]

 

Excel 파일이 버전에 따라서.. OleDB Connection String 이 다릅니다.

즉, xls 인지.. xlsx 인지에 따라서 다르게 처리해야 되는데...

기본적으로 확장명으로 비교할 수도 있겠지만.. 프로그램 만드는데 내부에서 쓰는 데이터 떡하니

xls 하기도 머시기 하고.. xxx 면 xls 라고 소스에서 비교할 수도 있겠지만.. 좀 아닌것 같아서

일단 확장명 상관없이 xls 인지 xlsx 인지 알아내는 방법을 보면... 아래처럼 2개가 있습니다.

 

A. Excel 를 연동해서 파일을 로딩.. 파일 정보를 본다.

B. Excel 파일을 열어서 맨 앞의 file header 부분을 본다.

 

A 로 하자니.. 실제로 두번 읽게 되니 -_-;; 글고 좀 느리구요.. B 로 해보겠습니다.

 

        public static int ExcelFileType(string XlsFile)
        { 

            // 요거이 비교할 파일 데이터 입니다.
            byte[,] ExcelHeader = {
                { 0xD0, 0xCF, 0x11, 0xE0, 0xA1 }, // XLS  File Header
                { 0x50, 0x4B, 0x03, 0x04, 0x14 }  // XLSX File Header
            };

            // result -2=error, -1=not excel , 0=xls , 1=xlsx
            int result = -1;

            FileInfo FI = new FileInfo(XlsFile);
            FileStream FS = FI.Open(FileMode.Open);

            try
            {
                byte[] FH = new byte[5];

                FS.Read(FH, 0, 5);

                for (int i = 0; i < 2; i++)
                {
                    for (int j = 0; j < 5; j++)
                    {
                        if (FH[j] != ExcelHeader[i, j]) break;
                        else if (j == 4) result = i;
                    }
                    if (result >= 0) break;
                }
            }
            catch (Exception e)
            {
                result = (-2);
                //throw e;
            }
            finally
            {
                FS.Close();                
            }
            return result;
        }

 

와 같이 되겠습니다. 머.. 단순하죠.. 파일 열어서 5 byte 비교해서.. xls 인지 xlsx 인지..

excel 파일이 아닌지를 알아내는 것입니다.

 

[ OleDB Connection String ]

 

자.. 어느넘이 어느 넘인지 알았으니.. OleDB Connection String 을 만들어 봅시다요..

각 각 다음과 같습니다만.. 중요한 것만 내용에 넣었으니.. 필요한게 더 있으면 추가를...

아래의 형태는 string.Format 함수로 사용할 format 용 서식입니다.

 

        // 확장명 XLS (Excel 97~2003 용)
        private const string ConnectStrFrm_Excel97_2003 =
            "Provider=Microsoft.Jet.OLEDB.4.0;" +
            "Data Source=\"{0}\";" +
            "Mode=ReadWrite|Share Deny None;" +
            "Extended Properties='Excel 8.0; HDR={1}; IMEX={2}';" +
            "Persist Security Info=False";

 

        // 확장명 XLSX (Excel 2007 이상용)
        private const string ConnectStrFrm_Excel =
            "Provider=Microsoft.ACE.OLEDB.12.0;" +
            "Data Source=\"{0}\";" +
            "Mode=ReadWrite|Share Deny None;" +
            "Extended Properties='Excel 12.0; HDR={1}; IMEX={2}';" +
            "Persist Security Info=False";

 

중요한 건 Provider 가 무언지와 Extended Properties (<- 요게 Excel 파일에 대한 옵션) 입니다.

Extended 보면 HDR 과 IMEX 속성이 있는데 이것이 중요합니다.

HDR 은 Excel 의 첫번째 줄의 데이터를 Field 명으로 인식 할 것인지 여부 (YES , NO) 이고..

IMEX 는 데이터 형식을 어떻게 적용할 것인지 옵션인데, 만약 그 줄의 데이터의 표본이 정수라면

필드가 생성될 때 정수형으로 생성됩니다. 일단은 IMEX=1 로 해서 걍 무시하고 무조건 string 으로

하겠습니다. (다음 버전을 만든다면 속성까지 다 하는 방향으로..)

머.. 여기 까지 왔으면 사실 대부분 그냥 만드실 수 있겠지만.. 그래도 노가다를 줄이기 위해..

소스를 올려 놓겠습니다... (-o- ;)a

 

[ Excel 파일을 DataSet 으로.. ]

 

아.. 참고로.. Excel 파일을 DataSet 으로 바꾸는 순간만을 제외하면 Excel 파일을 사용하지

않습니다. 즉.. 메모리에 로딩한 다음 데이터가 바뀐다고 Excel 파일도 같이 수정되지는 않습니다.

읽을 때도.. 읽는 당시만, 저장할 때도 저장하는 당시만 파일에 lock 이 걸리고 그 전,후에는

엑셀 파일과 전혀~ 상관 안합니다.

 

    첨부된 소스의        

    private static DataSet OpenExcel(string FileName, bool UseHeader)

    를 참고해 주세요~

 

[ DataSet 을 Excel 파일로.. ]

 

    첨부된 소스의        

    private static bool SaveExcel(string FileName, DataSet DS, bool ExistDel, bool OldExcel)

    를 참고해 주세요~

 

첨부된 소스를 사용하실 꺼라면..

OpenExcelDB, SaveExcelDB 두개를 사용하세요..

 

나중에 소스 업데이트를 하면 OpenExcel 이랑 SaveExcel 는 내용이 변경될 것인지라..

업데이트된 소스로 엎어 쳤을 때 에러날 수 있습니다.

 

첨부된 Source 사용법은 다운 받은 소스를 Project 에 추가해 주시고...

사용할 소스의 using 절 부분에 아래줄 추가..

 

using LiAsExcelDatabase;

 

사용하는 것은 아래처럼 사용하시믄 됩니다..

 

                    DataSet DS = LiAsExcelDB.OpenExcelDB("C:\\Temp.xlsx");
                    LiAsExcelDB.SaveExcelDB("C:\\Temp_save.dat",DS);

 

질문이 있으시면.. 이 글의 답글로 남겨주시면 고맙겠습니다.



[출처] C# 에서 Excel 로 데이터 기록 및 읽기 [OleDB]|작성자 애쁠


Posted by blueasa

댓글을 달아 주세요

  1. 이전 댓글 더보기
  2. 2014.10.01 03:04 신고 blueasa  댓글주소  수정/삭제  댓글쓰기

    안녕하세요.
    우선 올려진 글만봐서는 파일에 대한 ConnectionString 셋팅이 잘못된건지 체크해봐야 될 것 같습니다.
    엑셀은 버전이 올라가면서 .xls와 .xlsx로 나눠졌는데요.
    두 포멧이 달라서 ConnectionString도 다릅니다.
    우선 저는 Win7 x64/VS2010에서 작업했습니다.
    소스는 대충 아래와 같이 했습니다.
    참조해 보셨으면 합니다.

    String connectionString = "";
    if (dialog.SafeFileName.Contains(".xlsx";))
    {
    connectionString = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=Excel 12.0", dialog.FileName);
    }
    else if (dialog.SafeFileName.Contains(".xls";))
    {
    connectionString = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=Excel 8.0;", dialog.FileName);
    }

    using (OleDbConnection excelConnection = new OleDbConnection(connectionString))
    {
    DataTable dtSheets = new DataTable();

    try
    {
    excelConnection.Open();
    dtSheets = excelConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

    // ToDo
    }

    dtSheets.Dispose();
    if (excelConnection != null)
    excelConnection.Close();
    }

    혹시나 싶어서 참조할만한 링크도 남깁니다.
    잘 해결 되셨으면 합니다. (_ _)
    링크1 : http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=17&MAEULNo=8&no=145967&ref=145964
    링크2 : http://deeplu.blogspot.kr/2012/11/microsoftjetoledb40.html

  3. 2014.12.22 00:01 ronald03  댓글주소  수정/삭제  댓글쓰기

    계속 실패하고 있었는데 이 소스로 하니까 너무 잘되네요 ㅠㅠ 감사합니다~!!

  4. 2015.01.12 16:25 초보  댓글주소  수정/삭제  댓글쓰기

    친절한 설명 감사드립니다 ^^ 잘 배우고 갑니다

  5. 2015.01.21 11:31 구식  댓글주소  수정/삭제  댓글쓰기

    좋은내용과 친절한 설명 너무 감사드립니다
    자주 구독 하겠습니다^^ 꾸벅

  6. 2015.01.21 20:35 supercrat  댓글주소  수정/삭제  댓글쓰기

    땡큐 감사합니다.
    오랜만에 엑셀파일 쓸려고하니 xlsx file에서 오류가..
    덕분에 쉽게 갑니다.

  7. 2015.01.29 00:33 망고땡  댓글주소  수정/삭제  댓글쓰기

    엑셀 저장하고 불러오고..오랫만이라 잘 안되었는데...
    덕분에 잘 해결 되었습니다
    소스 오픈 감사합니다...

  8. 2015.02.09 12:43 신고 배고픈멍멍이  댓글주소  수정/삭제  댓글쓰기

    좋은 글 감사합니다 ㅎ
    막상 글들 많이 봤다고 생각했는데 여전히 못 본 좋은 글들이 많이 남아있네요!!ㅎ
    매번 좋은 글 감사합니다~ㅎ

  9. 2015.04.23 15:57 서우르  댓글주소  수정/삭제  댓글쓰기

    좋은 글 감사합니다. MFC 하다가 C# 공부 중인데.. 블로그에 좋은 글들이 많아서 큰 도움 되고 있습니다.
    C#엔 참 편리하고 좋은 것들이 많네요 ㅎㅎ 자주 방문하며 도움 얻어가겠습니다.

    • 2015.04.23 19:48 신고 blueasa  댓글주소  수정/삭제

      C#이 코딩을 참 편하게 해주는 것 같아요.
      예전엔 느리다고 말이 많았었는데..
      요즘은 포팅엔진들이 잘나와서 알아서 처리해주니 좋은 세상이네요. :)
      아무튼..
      도움 되셨다니 좋네요.
      좋은 하루 되세요~

  10. 2015.08.06 12:43 초보자2  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 소중한 게시물 잘보고있습니다 다름이 아니라 위의 소스를 사용하지는 않았고 C#프로젝트에서 oledb를 사용하여 엑셀 테이블을 수정하고싶은데 ExecuteNonQuery() 를 할때 Operation must use an updateable query. 오류가 나서 진행이 되지 않습니다ㅠㅠ 혹시나 아시는 내용이면 조언 부탁드립니다ㅠㅠ
    string connection_str = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source='{0}';Mode=ReadWrite;Extended Properties='Excel 12.0;HDR=Yes;IMEX=1'", fileName);

    OleDbConnection MyConnection2 = new OleDbConnection(connection_str);
    MyConnection2.Open();
    myCommand.Connection = MyConnection2;
    sql = string.Format("INSERT INTO [{0}$] (RoomId, ItemId) VALUES(1,2);", tableName);
    myCommand.CommandText = sql;
    myCommand.ExecuteNonQuery();

    • 2015.08.07 09:40 신고 blueasa  댓글주소  수정/삭제

      안녕하세요.
      저도 오랜만에 봐서 정확히는 말씀드릴 수 없을 것 같습니다만..

      1) 우선 눈에 띄는건 connection_str이 다른데요.
      본문에 있는걸로 대체해 보시겠어요?
      // 확장명 XLS (Excel 97~2003 용)
      private const string ConnectStrFrm_Excel97_2003 =
      "Provider=Microsoft.Jet.OLEDB.4.0;" +
      "Data Source=\"{0}\";" +
      "Mode=ReadWrite|Share Deny None;" +
      "Extended Properties='Excel 8.0; HDR={1}; IMEX={2}';" +
      "Persist Security Info=False";

      // 확장명 XLSX (Excel 2007 이상용)
      private const string ConnectStrFrm_Excel =
      "Provider=Microsoft.ACE.OLEDB.12.0;" +
      "Data Source=\"{0}\";" +
      "Mode=ReadWrite|Share Deny None;" +
      "Extended Properties='Excel 12.0; HDR={1}; IMEX={2}';" +
      "Persist Security Info=False";


      2) 혹시 엑셀파일이 열려있는건 아닌가요?

      아무튼..가능하면 위 파일 소스를 한 번 보시는 걸 추천 드립니다.
      아래는 ExecuteNonQuery() 함수가 포함된 SaveExcel() 함수입니다.
      도움이 되실지 모르지만 이거라도..

      /// <summary>
      /// DataSet 을 Excel 파일로 저장한다.
      /// </summary>
      /// <param name="FileName">
      /// Excel File 명 PullPath
      /// </param>
      /// <param name="DS">
      /// Excel 로 저장할 대상 DataSet 객체.
      /// </param>
      /// <param name="ExistDel">
      /// 동일한 파일명이 있을 때 삭제 할 것인지 여부, 파일이 있고 false 면 저장안하고 그냥 false 를 리턴.
      /// </param>
      /// <param name="OldExcel">
      /// xls 형태로 저장할 것인지 여부, false 이면 xlsx 형태로 저장함.
      /// </param>
      private static bool SaveExcel(string FileName, DataSet DS, bool ExistDel, bool OldExcel)
      {
      bool result = true;

      if (File.Exists(FileName))
      if (ExistDel) File.Delete(FileName);
      else return result;

      string TempFile = FileName;
      // 파일 확장자가 xls 이나 xlsx 가 아니면 아예 파일을 안만들어서
      // 템프파일로 생성후 지정한 파일명으로 변경..

      OleDbConnection OleDBConn = null;

      try
      {
      OleDbCommand Cmd = null;
      string ConnStr = "";

      if (OldExcel)
      {
      TempFile = TempFile + ".xls";
      ConnStr = string.Format(ConnectStrFrm_Excel97_2003, TempFile, "YES", "0";);
      }
      else
      {
      TempFile = TempFile + ".xlsx";
      ConnStr = string.Format(ConnectStrFrm_Excel, TempFile, "YES", "0";);
      }

      OleDBConn = new OleDbConnection(ConnStr);
      OleDBConn.Open();

      // Create Table(s).. : 테이블 단위 처리
      foreach (DataTable DT in DS.Tables)
      {
      String TableName = DT.TableName;

      StringBuilder FldsInfo = new StringBuilder();
      StringBuilder Flds = new StringBuilder();

      // Create Field(s) String : 현재 테이블의 Field 명 생성
      foreach (DataColumn Column in DT.Columns)
      {
      if (FldsInfo.Length > 0) {
      FldsInfo.Append(",";);
      Flds.Append(",";);
      }

      FldsInfo.Append("[" + Column.ColumnName.Replace("'", "''";) + "] CHAR(255)";);
      Flds.Append( Column.ColumnName.Replace("'", "''";) );
      }

      // Table Create
      Cmd = new OleDbCommand("CREATE TABLE " + TableName + "(" + FldsInfo.ToString() + ";)", OleDBConn);
      Cmd.ExecuteNonQuery();

      // Insert Data
      foreach (DataRow DR in DT.Rows)
      {
      StringBuilder Values = new StringBuilder();
      foreach (DataColumn Column in DT.Columns)
      {
      if (Values.Length > 0) Values.Append(",";);
      Values.Append("'" + DR[Column.ColumnName].ToString().Replace("'", "''";) + "'";);
      }

      Cmd = new OleDbCommand(
      "INSERT INTO [" + TableName + "$]"+
      "(" + Flds.ToString() + ";) "+
      "VALUES (" + Values.ToString() + ";)",
      OleDBConn);
      Cmd.ExecuteNonQuery();
      }
      }
      }
      catch (Exception)
      {
      result = false;
      }
      finally
      {
      if (OleDBConn != null) OleDBConn.Close();
      try
      {
      if (File.Exists(TempFile))
      {
      File.Move(TempFile, FileName);
      }
      }
      catch { }
      }
      return result;
      }

  11. 2015.08.07 10:24 초보자2  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 참고만하고 가져다 쓰진않고 직접해보려 했는데 적어주신 소스로 작동시키니까 쿼리문이 잘 넘어가네요. 뭔가 빼먹은 부분이 있나봅니다ㅠㅠ잘 보고 다시해봐야겠네요 정말 감사드립니다!!ㅠㅠ

    • 2015.08.07 10:39 신고 blueasa  댓글주소  수정/삭제

      직접 해보는 건 좋은 습관이라고 생각합니다.
      그 습관 계속 지켜나가시길 바랄게요. :)
      아무튼 해결되었다니 다행이네요.
      해결후에 차근차근 비교하면서 다시 한 번 체크해 보세요~
      포스트모템 한다는 생각으로.. ^________^

  12. 2015.08.07 21:20 초보자2  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 민폐지만 질문 하나만 더해도 될까요 많은 힘을 얻고있습니다 감사합니다ㅠㅠ
    지금 SaveExcel을 사용하여 Excel파일을 만들어 내는데 성공하였는데,
    OldExcel = false로 주고 파일 확장자를 .xlsx로 생성하였는데도
    "파일 형식 또는 파일 확장명이 잘못되어 열수 없다"는 메세지박스가 뜹니다ㅠㅠ
    확장자를 xls로 변경하면 "파일 형식 및 확장명이 일치하지 않다"라고 나오지만 그래도 여시겠습니까?라는 선택지가 나와서 "예"를 누르면 데이터도 잘 들어가있고 열리긴합니다.

    xlsx확장명으로 잘 저장이 되셨는지 이런 문제가 있으셨는지 궁금해서 질문드렸습니다.
    긴 글 읽어주셔서 감사하고 주말 잘보내세요!!ㅋㅋ

    • 2015.08.10 10:11 신고 blueasa  댓글주소  수정/삭제

      음..
      저는 현재 잘쓰고 있습니다.
      두 확장자 다 되지만 현재는 xlsx만 쓰고 있는데요.
      예상으로는 xls로 만들어진 파일을 xlsx로 저장하려고 해서 생기는 문제는 아닌가..싶긴합니다.
      xlsx파일을 하나 새로 만들어서 테스트 해 보시겠어요?

  13. 2016.03.08 11:04 초보자02  댓글주소  수정/삭제  댓글쓰기

    안녕하세요
    첨부파일 다운 받았습니다..
    좋은 소스 감사합니다.

  14. 2016.03.22 11:41 학생1  댓글주소  수정/삭제  댓글쓰기

    안녕하세요..! 현재 공부하고 있는 부분에 대해서 많은 도움이 되었습니다..!
    몇 일 헤매다가 결국 해결하지 못해서 이곳에 질문을 남기는데요..!
    엑셀 첮 줄을 헤더로 사용하고 싶지 않아서 OpenExcelDB를 FALSE 값을 주면..
    EXPORT 되는 엑셀 맨 윗줄에 F1, F2,F3..해서 첫 줄이 생겨납니다...ㅜㅜ DELETE나 REMOVE를 사용하려고 해도 이 ROW에는 적용이
    안되더라구요..! 저 첫쩨줄을 업앨 수 있는 방법이 있을까요..?

    • 2016.03.22 15:07 신고 blueasa  댓글주소  수정/삭제

      안녕하세요.
      우선 어떻게 사용하려는지 모르겠습니다만, UseHeader 변수는 사용자가(자신)가 셋팅한 임의의 헤더명을 쓸거냐 엑셀 칼럼명(F1~...)을 쓸거냐일 뿐 헤더는 있어야 됩니다.
      헤더가 없으면 .db로 만들어졌을 때 찾을 방법이 없습니다.
      변수명이 있어야 해당 변수에 접근 가능하듯이요.
      헤더가 필요없다면 UseHeader를 false로 하시고, F1등이 나오는 Row는 무시하고 다음 Row부터 읽으시면 될거라 생각합니다.
      잘 해결되시길 바랄게요. :)

  15. 2016.03.23 18:26 학생1  댓글주소  수정/삭제  댓글쓰기

    답변감사합니다...! 음..소스에선 create table을 하면서 excel에 쓰여지게 되있는것 같은데.. 어떤 부분에서 f1줄을 제외하고 읽을 수 있을까요..?ㅜㅜ 몇일째 안풀리네요ㅜㅜ...

    • 2016.03.25 09:30 신고 blueasa  댓글주소  수정/삭제

      안녕하세요.
      읽어들인 엑셀을 저장하시려는 건가요?
      SaveExcel을 하시는건데 첫 줄(Row)을 없애고 싶으신거라면
      소스 상
      private static bool SaveExcel(string FileName, DataSet DS, bool ExistDel, bool OldExcel)
      부분에 보시면
      foreach (DataRow DR in DT.Rows)
      하는 부분이 있습니다.
      여기에 중단점을 걸어서 디버깅 해보시면 아시겠지만 여기서 첫 줄(Row)만 건너띄는 소스를 넣으시면 될거라 생각합니다.
      확인해 보시겠어요?

  16. 2016.03.28 15:54 학생1  댓글주소  수정/삭제  댓글쓰기

    안녕하세요..! 답변 감사드립니다..
    네..SaveExcel을 하는 건데..중단점을 걸어서 디버깅 했을 때 첫번재로 들어오는 row가 f1, f2 등이 나오는 row가 아니라 그 다음 데이터 row가 들어옵니다..ㅜㅜ 그래서 그쪽에서는 처리할 수가 없더라구요.. F1, F2는 CreaeTable을 했을 때의 컬럼으로 들어가는 것 같습니다..ㅜㅜ 해결할수없는 걸까요..흑흑 너무답답하네요ㅜㅜ

    • 2016.03.28 16:41 신고 blueasa  댓글주소  수정/삭제

      음..
      F1 등이 나오는 Row를 없애고 싶으셨던 것 아닌가요?
      SaveExcel 할 때 F1등의 Row를 제외하고 다음 Row부터 읽는다면 원하시는 상태가 아닌건가요?
      뭘 하고 싶으신건지 이해를 못하겠습니다. -ㅅ-;;

  17. 2016.06.27 16:25 초심자  댓글주소  수정/삭제  댓글쓰기

    감사합니다. 참고하여 학습하겠습니다. 블러그 번창하시고 언제나 좋은 자료 감사합니다 ~*

  18. 2016.07.26 15:25 초시자  댓글주소  수정/삭제  댓글쓰기

    좋은 정보를 공유해 주셔서 감사드립니다
    초심자로써 지푸라기라도 잡는 심정으로 인터넷 서핑중 만나게 되어서 기대와 희망을 갖고 열공해 보겠습니다

    • 2016.07.31 19:44 신고 blueasa  댓글주소  수정/삭제

      리플 감사합니다.
      모르는 걸 배우는 게 지겹고 힘들긴 하지만 해냈을 때 뿌듯함으로 살아가는 게 계속 하는 이유이지 않나 싶네요.
      힘들겠지만 즐겁게 개발하시길 바랄게요. :)

  19. 2017.03.02 17:09 두둥  댓글주소  수정/삭제  댓글쓰기

    관련 프로젝트 진행중인데 좋은 정보 감사합니다.

    한가지 궁금한점이 있는데 엑셀파일 버전(2013, 2014, 등등)에 따라서 못 읽어 올 수 있는 경우가 생길수 있나요?

    • 2017.03.02 17:13 신고 blueasa  댓글주소  수정/삭제

      안녕하세요.
      본문에 보시면

      // 확장명 XLS (Excel 97~2003 용)
      // 확장명 XLSX (Excel 2007 이상용)

      위와 같은 주석이 있는데요.
      엑셀은 버전에 따라 xls/xlsx로 구분되는데요. 그에 맞게 만들어져 있다면 상위 호환도 되기때문에 알아서 처리 되는걸로 압니다.

      좋은 하루 되세요. :)

      P.s. 저는 엑셀 2013 버전 씁니다.

  20. 2017.03.16 15:07 애증의 닷넷  댓글주소  수정/삭제  댓글쓰기

    윈폼 개발중 해당 자료를 보게되서 슬적 사용하려 합니다.
    감사합니다 ㅎㅎ

  21. 2017.04.14 18:19 jazz  댓글주소  수정/삭제  댓글쓰기

    안녕하세요, 올려주신 소스를 이용해서 잘 사용하고 있습니다 . 이점에 너무 감사합니다. 문의항것이 있는데요 엑셀파링 Open중에 IE가 다운되더라구요 그래서 봤더니 용량이 적은 파일은 정상 적인데 용량이 큰 엑셀은 않되는같더라구요 해결할 방법이 없을까요?
    엑셀 파일의 용량이 5.1MB이고 엑셀행수는 1만 정도 되구요 컬럼은 'DH' 한 112 컬럼 됩니다. 꼭 좀 부탁 드립니다.

    • 2017.04.18 14:48 신고 blueasa  댓글주소  수정/삭제

      안녕하세요.
      요즘 바빠서 늦게 답변 드리게 되네요. 죄송합니다.
      말씀해주신 내용으로 예상되는 부분은 처리할 데이터 양이 많아서 for(or foreach)문에서 너무 오래 잡혀있어서 (응답없음) 등으로 빠지는 문제가 나오는 게 아닐까 싶은데요.
      이 문제라면 비동기 처리 방식으로 바꿔야 되지 않나 싶긴하네요.
      C#이니 BackgroundWorker를 써보는 게 어떨까 싶습니다. :)

      [BackgroundWorker 참조] http://blueasa.tistory.com/1260

파일을 열 때 에러가 났다는 것인데 파일이 존재함에도 불구하고 에러가 난 것입니다.  

이런 경우는 해당 파일이 다른 프로세스에서 사용중이기 때문에 나옵니다.  

그래서 원본 파일을 템프 파일에 복사한 후 원본이 아닌 복사본을 열어버리고.. 나중에 다시 템프 파일을 삭제해 버리는 것이죠. 

 

                        string fileTemp = fileFullNm + "_tmp";
                        File.Copy(fileFullNm, fileTemp, true);

                        //다른프로세서가 사용중인것을 방지
                        FileStream fs = new FileStream(fileTemp, FileMode.Open);

 

                        ~~~~

                        File.Delete(fileTemp);




[출처] C# 다른 프로세스가 사용중이라면서 에러가 나는경우에 이렇게|작성자 doghole


Posted by blueasa

댓글을 달아 주세요

  1. 2018.06.02 15:22  댓글주소  수정/삭제  댓글쓰기

    위 코드를 어디에다 적어야 하나요 ???

    • 2018.06.04 13:30 신고 blueasa  댓글주소  수정/삭제

      안녕하세요.
      위 내용은 파일을 직접 수정하지 못할수도 있으니 복사해서 별도의 파일을 만들고, 복사된 파일을 열어서 사용하기 위해서 설명한 부분입니다.
      파일 오픈이 필요한 시점에 해당 방식으로 쓰시면 됩니다. :)



링크 : http://warmz.tistory.com/365

Posted by blueasa

댓글을 달아 주세요


Link : http://forum.codecall.net/topic/71788-reading-excel-files-in-c/

'Programming > C#' 카테고리의 다른 글

다른 프로세스가 사용중이라면서 에러가 나는경우에 이렇게  (2) 2014.03.17
제네릭(Generic)과 제약조건  (0) 2014.03.13
Reading Excel Files in C#  (0) 2014.03.12
C# 의 Shift 비트 연산 정리  (0) 2013.12.18
Copy List to List  (0) 2013.10.10
Sorting  (0) 2013.10.02
Posted by blueasa

댓글을 달아 주세요