diff --git a/README.md b/README.md index ba8630d..f1a6237 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,11 @@ Checkout the [introduction video.](http://www.youtube.com/watch?v=t3BEUP0OTFM) You can use NuGet to quickly add LinqToExcel to your project. Just search for `linqtoexcel` and install the package. #### Access Database Engine -In order to use LinqToExcel, you need to install the Microsoft [Microsoft Access Database Engine 2010 Redistributable](https://www.microsoft.com/en-in/download/details.aspx?id=13255). If it's not installed, you'll get the following exception: +In order to use LinqToExcel, you need to install either of the [Microsoft Access Database Engine 2010 Redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=13255), [Microsoft Access 2013 Runtime](https://www.microsoft.com/en-us/download/details.aspx?id=39358), [Microsoft Access 2016 Runtime](https://www.microsoft.com/en-us/download/details.aspx?id=50040). If it's not installed, you'll get the following exception: The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.' + The 'Microsoft.ACE.OLEDB.15.0' provider is not registered on the local machine.' + The 'Microsoft.ACE.OLEDB.16.0' provider is not registered on the local machine.' *Both a 32-bit and 64-bit version are available, select the one that matches your project settings.* You can only have one of them installed at a time. diff --git a/src/LinqToExcel/Domain/DatabaseEngine.cs b/src/LinqToExcel/Domain/DatabaseEngine.cs new file mode 100644 index 0000000..30ad31b --- /dev/null +++ b/src/LinqToExcel/Domain/DatabaseEngine.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace LinqToExcel.Domain +{ + public enum DatabaseEngine + { + Jet, + Ace2010, + Ace2013, + Ace2016 + } +} diff --git a/src/LinqToExcel/ExcelQueryFactory.cs b/src/LinqToExcel/ExcelQueryFactory.cs index efd04bb..3056256 100644 --- a/src/LinqToExcel/ExcelQueryFactory.cs +++ b/src/LinqToExcel/ExcelQueryFactory.cs @@ -87,6 +87,7 @@ public ExcelQueryFactory(string fileName) public ExcelQueryFactory(string fileName, ILogManagerFactory logManagerFactory) { FileName = fileName; + DatabaseEngine = ExcelUtilities.DefaultDatabaseEngine(); OleDbServices = OleDbServices.AllServices; if (logManagerFactory != null) { @@ -95,15 +96,22 @@ public ExcelQueryFactory(string fileName, ILogManagerFactory logManagerFactory) } } - #region Other Methods - /// - /// Add a column to property mapping + /// Sets the database engine to use + /// (Spreadsheets ending in xlsx, xlsm, and xlsb must use the Ace database engine) + /// (If running 64 bit this defaults to ACE (JET doesn't work anyway), if running 32 bit this detaults to JET) /// - /// Class type to return row data as - /// Class property to map to - /// Worksheet column name to map from - public void AddMapping(Expression> property, string column) + public DatabaseEngine DatabaseEngine { get; set; } + + #region Other Methods + + /// + /// Add a column to property mapping + /// + /// Class type to return row data as + /// Class property to map to + /// Worksheet column name to map from + public void AddMapping(Expression> property, string column) { AddMapping(GetPropertyName(property), column); } @@ -224,7 +232,8 @@ internal ExcelQueryConstructorArgs GetConstructorArgs() return new ExcelQueryConstructorArgs() { FileName = FileName, - StrictMapping = StrictMapping, + DatabaseEngine = DatabaseEngine, + StrictMapping = StrictMapping, ColumnMappings = _columnMappings, Transformations = _transformations, UsePersistentConnection = UsePersistentConnection, diff --git a/src/LinqToExcel/IExcelQueryFactory.cs b/src/LinqToExcel/IExcelQueryFactory.cs index ff543d9..80c8e70 100644 --- a/src/LinqToExcel/IExcelQueryFactory.cs +++ b/src/LinqToExcel/IExcelQueryFactory.cs @@ -284,5 +284,10 @@ public interface IExcelQueryFactory : IDisposable /// /// Worksheet name to get the list of column names from IEnumerable GetColumnNames(string worksheetName); - } + + /// + /// Sets the database engine to use (spreadsheets ending in xlsx, xlsm, xlsb will always use the Ace engine) + /// + DatabaseEngine DatabaseEngine { get; set; } + } } diff --git a/src/LinqToExcel/Query/ExcelQueryArgs.cs b/src/LinqToExcel/Query/ExcelQueryArgs.cs index 6a6fe8d..b16fae8 100644 --- a/src/LinqToExcel/Query/ExcelQueryArgs.cs +++ b/src/LinqToExcel/Query/ExcelQueryArgs.cs @@ -10,7 +10,8 @@ namespace LinqToExcel.Query internal class ExcelQueryArgs { internal string FileName { get; set; } - internal string WorksheetName { get; set; } + internal DatabaseEngine DatabaseEngine { get; set; } + internal string WorksheetName { get; set; } internal int? WorksheetIndex { get; set; } internal Dictionary ColumnMappings { get; set; } internal Dictionary> Transformations { get; private set; } @@ -28,7 +29,7 @@ internal class ExcelQueryArgs internal int CodePageIdentifier { get; set; } internal ExcelQueryArgs() - : this(new ExcelQueryConstructorArgs()) + : this(new ExcelQueryConstructorArgs() { DatabaseEngine = ExcelUtilities.DefaultDatabaseEngine() }) { OleDbServices = OleDbServices.AllServices; } @@ -41,7 +42,8 @@ internal ExcelQueryArgs(ExcelQueryArgs orig) : this() if (orig != null) { FileName = orig.FileName; - WorksheetName = orig.WorksheetName; + DatabaseEngine = orig.DatabaseEngine; + WorksheetName = orig.WorksheetName; WorksheetIndex = orig.WorksheetIndex; ColumnMappings = orig.ColumnMappings; Transformations = orig.Transformations; @@ -62,7 +64,8 @@ internal ExcelQueryArgs(ExcelQueryArgs orig) : this() internal ExcelQueryArgs(ExcelQueryConstructorArgs args) { FileName = args.FileName; - ColumnMappings = args.ColumnMappings ?? new Dictionary(); + DatabaseEngine = args.DatabaseEngine; + ColumnMappings = args.ColumnMappings ?? new Dictionary(); Transformations = args.Transformations ?? new Dictionary>(); StrictMapping = args.StrictMapping ?? StrictMappingType.None; UsePersistentConnection = args.UsePersistentConnection; diff --git a/src/LinqToExcel/Query/ExcelQueryConstructorArgs.cs b/src/LinqToExcel/Query/ExcelQueryConstructorArgs.cs index af653b2..c2c7336 100644 --- a/src/LinqToExcel/Query/ExcelQueryConstructorArgs.cs +++ b/src/LinqToExcel/Query/ExcelQueryConstructorArgs.cs @@ -17,7 +17,8 @@ public ExcelQueryConstructorArgs() } internal string FileName { get; set; } - internal Dictionary ColumnMappings { get; set; } + internal DatabaseEngine DatabaseEngine { get; set; } + internal Dictionary ColumnMappings { get; set; } internal Dictionary> Transformations { get; set; } internal StrictMappingType? StrictMapping { get; set; } internal bool UsePersistentConnection { get; set; } diff --git a/src/LinqToExcel/Query/ExcelUtilities.cs b/src/LinqToExcel/Query/ExcelUtilities.cs index c43af20..426054a 100644 --- a/src/LinqToExcel/Query/ExcelUtilities.cs +++ b/src/LinqToExcel/Query/ExcelUtilities.cs @@ -6,283 +6,347 @@ using System.IO; using LinqToExcel.Extensions; +using LinqToExcel.Domain; namespace LinqToExcel.Query { - public static class ExcelUtilities + public static class ExcelUtilities + { + internal static string GetConnectionString(ExcelQueryArgs args) { - internal static string GetConnectionString(ExcelQueryArgs args) + var connString = ""; + var fileNameLower = args.FileName.ToLower(); + var provider = ""; + var version = ""; + switch (args.DatabaseEngine) + { + case DatabaseEngine.Ace2016: + provider = "Microsoft.ACE.OLEDB.16.0"; + version = "12.0"; + break; + case DatabaseEngine.Ace2013: + provider = "Microsoft.ACE.OLEDB.15.0"; + version = "12.0"; + break; + case DatabaseEngine.Ace2010: + provider = "Microsoft.ACE.OLEDB.12.0"; + version = "12.0"; + break; + case DatabaseEngine.Jet: + provider = "Microsoft.Jet.OLEDB.4.0"; + version = "8.0"; + break; + } + + if (fileNameLower.EndsWith("xlsx")) + { + if (args.DatabaseEngine == DatabaseEngine.Jet) { - var connString = ""; - var fileNameLower = args.FileName.ToLower(); - - if (fileNameLower.EndsWith("xlsx") || - fileNameLower.EndsWith("xlsm")) - { - connString = string.Format( - @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};OLE DB Services={1:d};Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1""", - args.FileName, - args.OleDbServices); - } - else if (fileNameLower.EndsWith("xlsb")) - { - connString = string.Format( - @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};OLE DB Services={1:d};Extended Properties=""Excel 12.0;HDR=YES;IMEX=1""", + throw new Exception("use ace database engine open excel workbook (.xlsx)."); + } + connString = string.Format( + @"Provider={2};Data Source={0};OLE DB Services={1:d};Extended Properties=""Excel {3} Xml;HDR=YES;IMEX=1""", + args.FileName, + args.OleDbServices, provider, version); + } + else if (fileNameLower.EndsWith("xls")) + { + connString = string.Format( + @"Provider={2};Data Source={0};OLE DB Services={1:d};Extended Properties=""Excel 8.0;HDR=YES;IMEX=1""", + args.FileName, + args.OleDbServices, provider); + } + else if (fileNameLower.EndsWith("xlsm")) + { + if (args.DatabaseEngine == DatabaseEngine.Jet) + { + throw new Exception("use ace database engine open excel macro-enabled workbook (.xlsm)."); + } + connString = string.Format( + @"Provider={2};Data Source={0};OLE DB Services={1:d};Extended Properties=""Excel {3} Macro;HDR=YES;IMEX=1""", + args.FileName, + args.OleDbServices, provider, version); + } + else if (fileNameLower.EndsWith("xlsb")) + { + if (args.DatabaseEngine == DatabaseEngine.Jet) + { + throw new Exception("use ace database engine open excel non-xml binary workbook (.xlsb)."); + } + connString = string.Format( + @"Provider={2};Data Source={0};OLE DB Services={1:d};Extended Properties=""Excel {3};HDR=YES;IMEX=1""", args.FileName, - args.OleDbServices); - } - else if (fileNameLower.EndsWith("csv")) - { - connString = string.Format( - @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};OLE DB Services={1:d};Extended Properties=""text;Excel 12.0;HDR=YES;IMEX=1""", + args.OleDbServices, provider, version); + } + else if (fileNameLower.EndsWith("csv")) + { + if (args.DatabaseEngine == DatabaseEngine.Jet) + { + connString = string.Format( + @"Provider={2};Data Source={0};OLE DB Services={1:d};Extended Properties=""text;HDR=YES;FMT=Delimited;IMEX=1""", + Path.GetDirectoryName(args.FileName), + args.OleDbServices, provider); + } + else + { + connString = string.Format( + @"Provider={2};Data Source={0};OLE DB Services={1:d};Extended Properties=""text;Excel {3};HDR=YES;IMEX=1""", Path.GetDirectoryName(args.FileName), - args.OleDbServices); - } - else - { - connString = string.Format( - @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};OLE DB Services={1:d};Extended Properties=""Excel 12.0;HDR=YES;IMEX=1""", - args.FileName, - args.OleDbServices); - } + args.OleDbServices, provider, version); + } + } + else + { + throw new System.Exception("unknown excel file type."); + } - if (args.NoHeader) - connString = connString.Replace("HDR=YES", "HDR=NO"); + if (args.NoHeader) + connString = connString.Replace("HDR=YES", "HDR=NO"); - if (args.ReadOnly) - connString = connString.Replace("IMEX=1", "IMEX=1;READONLY=TRUE"); + if (args.ReadOnly) + connString = connString.Replace("IMEX=1", "IMEX=1;READONLY=TRUE"); - if(args.CodePageIdentifier > 0) - connString = connString.Replace("IMEX=1",string.Format ("IMEX=1;CharacterSet={0:000}",args.CodePageIdentifier)); + if (args.CodePageIdentifier > 0) + connString = connString.Replace("IMEX=1", string.Format("IMEX=1;CharacterSet={0:000}", args.CodePageIdentifier)); - return connString; - } + return connString; + } - internal static IEnumerable GetWorksheetNames(string fileName) - { - return GetWorksheetNames(fileName, new ExcelQueryArgs()); - } + internal static IEnumerable GetWorksheetNames(string fileName) + { + return GetWorksheetNames(fileName, new ExcelQueryArgs()); + } - internal static IEnumerable GetWorksheetNames(string fileName, ExcelQueryArgs origArgs) - { - var args = new ExcelQueryArgs(origArgs); - args.FileName = fileName; - args.ReadOnly = true; - return GetWorksheetNames(args); - } + internal static IEnumerable GetWorksheetNames(string fileName, ExcelQueryArgs origArgs) + { + var args = new ExcelQueryArgs(origArgs); + args.FileName = fileName; + args.ReadOnly = true; + return GetWorksheetNames(args); + } - internal static OleDbConnection GetConnection(ExcelQueryArgs args) - { - if (args.UsePersistentConnection) - { - if (args.PersistentConnection == null) - args.PersistentConnection = new OleDbConnection(GetConnectionString(args)); + internal static OleDbConnection GetConnection(ExcelQueryArgs args) + { + if (args.UsePersistentConnection) + { + if (args.PersistentConnection == null) + args.PersistentConnection = new OleDbConnection(GetConnectionString(args)); - return args.PersistentConnection; - } + return args.PersistentConnection; + } - return new OleDbConnection(GetConnectionString(args)); - } + return new OleDbConnection(GetConnectionString(args)); + } - internal static IEnumerable GetWorksheetNames(ExcelQueryArgs args) - { - var worksheetNames = new List(); - - var conn = GetConnection(args); - try - { - if (conn.State == ConnectionState.Closed) - conn.Open(); - - var excelTables = conn.GetOleDbSchemaTable( - OleDbSchemaGuid.Tables, - new Object[] { null, null, null, "TABLE" }); - - worksheetNames.AddRange( - from DataRow row in excelTables.Rows - where IsTable(row) - let tableName = row["TABLE_NAME"].ToString() - .RegexReplace("(^'|'$)", "") - .RegexReplace(@"\$$", "") - .Replace("''", "'") - where IsNotBuiltinTable(tableName) - select tableName); - - excelTables.Dispose(); - } - finally - { - if (!args.UsePersistentConnection) - conn.Dispose(); - } - - return worksheetNames; - } + internal static IEnumerable GetWorksheetNames(ExcelQueryArgs args) + { + var worksheetNames = new List(); + + var conn = GetConnection(args); + try + { + if (conn.State == ConnectionState.Closed) + conn.Open(); + + var excelTables = conn.GetOleDbSchemaTable( + OleDbSchemaGuid.Tables, + new Object[] { null, null, null, "TABLE" }); + + worksheetNames.AddRange( + from DataRow row in excelTables.Rows + where IsTable(row) + let tableName = row["TABLE_NAME"].ToString() + .RegexReplace("(^'|'$)", "") + .RegexReplace(@"\$$", "") + .Replace("''", "'") + where IsNotBuiltinTable(tableName) + select tableName); + + excelTables.Dispose(); + } + finally + { + if (!args.UsePersistentConnection) + conn.Dispose(); + } + + return worksheetNames; + } - internal static bool IsTable(DataRow row) - { - var tableName = row["TABLE_NAME"].ToString(); + internal static bool IsTable(DataRow row) + { + var tableName = row["TABLE_NAME"].ToString(); - return tableName.EndsWith("$") || (tableName.StartsWith("'") && tableName.EndsWith("$'")); - } + return tableName.EndsWith("$") || (tableName.StartsWith("'") && tableName.EndsWith("$'")); + } - internal static bool IsNamedRange(DataRow row) - { - var tableName = row["TABLE_NAME"].ToString(); + internal static bool IsNamedRange(DataRow row) + { + var tableName = row["TABLE_NAME"].ToString(); - return (tableName.Contains("$") && !tableName.EndsWith("$") && !tableName.EndsWith("$'")) || !tableName.Contains("$"); - } + return (tableName.Contains("$") && !tableName.EndsWith("$") && !tableName.EndsWith("$'")) || !tableName.Contains("$"); + } - internal static bool IsWorkseetScopedNamedRange(DataRow row) - { - var tableName = row["TABLE_NAME"].ToString(); + internal static bool IsWorkseetScopedNamedRange(DataRow row) + { + var tableName = row["TABLE_NAME"].ToString(); - return IsNamedRange(row) && tableName.Contains("$"); - } + return IsNamedRange(row) && tableName.Contains("$"); + } - internal static bool IsNotBuiltinTable(string tableName) - { - return !tableName.Contains("FilterDatabase") && !tableName.Contains("Print_Area"); - } + internal static bool IsNotBuiltinTable(string tableName) + { + return !tableName.Contains("FilterDatabase") && !tableName.Contains("Print_Area"); + } - internal static IEnumerable GetColumnNames(string worksheetName, string fileName) - { - return GetColumnNames(worksheetName, fileName, new ExcelQueryArgs()); - } + internal static IEnumerable GetColumnNames(string worksheetName, string fileName) + { + return GetColumnNames(worksheetName, fileName, new ExcelQueryArgs()); + } - internal static IEnumerable GetColumnNames(string worksheetName, string fileName, ExcelQueryArgs origArgs) - { - var args = new ExcelQueryArgs(origArgs); - args.WorksheetName = worksheetName; - args.FileName = fileName; - return GetColumnNames(args); - } + internal static IEnumerable GetColumnNames(string worksheetName, string fileName, ExcelQueryArgs origArgs) + { + var args = new ExcelQueryArgs(origArgs); + args.WorksheetName = worksheetName; + args.FileName = fileName; + return GetColumnNames(args); + } - internal static IEnumerable GetColumnNames(string worksheetName, string namedRange, string fileName) - { - return GetColumnNames(worksheetName, namedRange, fileName, new ExcelQueryArgs()); - } + internal static IEnumerable GetColumnNames(string worksheetName, string namedRange, string fileName) + { + return GetColumnNames(worksheetName, namedRange, fileName, new ExcelQueryArgs()); + } - internal static IEnumerable GetColumnNames(string worksheetName, string namedRange, string fileName, ExcelQueryArgs origArgs) - { - var args = new ExcelQueryArgs(origArgs); - args.WorksheetName = worksheetName; - args.NamedRangeName = namedRange; - args.FileName = fileName; - return GetColumnNames(args); - } + internal static IEnumerable GetColumnNames(string worksheetName, string namedRange, string fileName, ExcelQueryArgs origArgs) + { + var args = new ExcelQueryArgs(origArgs); + args.WorksheetName = worksheetName; + args.NamedRangeName = namedRange; + args.FileName = fileName; + return GetColumnNames(args); + } - internal static IEnumerable GetColumnNames(ExcelQueryArgs args) + internal static IEnumerable GetColumnNames(ExcelQueryArgs args) + { + var columns = new List(); + var conn = GetConnection(args); + try + { + if (conn.State == ConnectionState.Closed) + conn.Open(); + + using (var command = conn.CreateCommand()) { - var columns = new List(); - var conn = GetConnection(args); - try - { - if (conn.State == ConnectionState.Closed) - conn.Open(); - - using (var command = conn.CreateCommand()) - { - command.CommandText = string.Format("SELECT TOP 1 * FROM [{0}{1}]", string.Format("{0}{1}", args.WorksheetName, "$"), args.NamedRangeName); - var data = command.ExecuteReader(); - columns.AddRange(GetColumnNames(data)); - } - } - finally - { - if (!args.UsePersistentConnection) - conn.Dispose(); - } - - return columns; + command.CommandText = string.Format("SELECT TOP 1 * FROM [{0}{1}]", string.Format("{0}{1}", args.WorksheetName, "$"), args.NamedRangeName); + var data = command.ExecuteReader(); + columns.AddRange(GetColumnNames(data)); } + } + finally + { + if (!args.UsePersistentConnection) + conn.Dispose(); + } + + return columns; + } - internal static IEnumerable GetColumnNames(IDataReader data) - { - var columns = new List(); - var sheetSchema = data.GetSchemaTable(); - foreach (DataRow row in sheetSchema.Rows) - columns.Add(row["ColumnName"].ToString()); + internal static IEnumerable GetColumnNames(IDataReader data) + { + var columns = new List(); + var sheetSchema = data.GetSchemaTable(); + foreach (DataRow row in sheetSchema.Rows) + columns.Add(row["ColumnName"].ToString()); - return columns; - } + return columns; + } - internal static IEnumerable GetNamedRanges(string fileName, string worksheetName) - { - return GetNamedRanges(fileName, worksheetName, new ExcelQueryArgs()); - } + internal static IEnumerable GetNamedRanges(string fileName, string worksheetName) + { + return GetNamedRanges(fileName, worksheetName, new ExcelQueryArgs()); + } - internal static IEnumerable GetNamedRanges(string fileName) - { - return GetNamedRanges(fileName, new ExcelQueryArgs()); - } + internal static IEnumerable GetNamedRanges(string fileName) + { + return GetNamedRanges(fileName, new ExcelQueryArgs()); + } - internal static IEnumerable GetNamedRanges(string fileName, ExcelQueryArgs origArgs) - { - var args = new ExcelQueryArgs(origArgs); - args.FileName = fileName; - args.ReadOnly = true; - return GetNamedRanges(args); - } + internal static IEnumerable GetNamedRanges(string fileName, ExcelQueryArgs origArgs) + { + var args = new ExcelQueryArgs(origArgs); + args.FileName = fileName; + args.ReadOnly = true; + return GetNamedRanges(args); + } - internal static IEnumerable GetNamedRanges(string fileName, string worksheetName, ExcelQueryArgs origArgs) - { - var args = new ExcelQueryArgs(origArgs); - args.FileName = fileName; - args.WorksheetName = worksheetName; - args.ReadOnly = true; - return GetNamedRanges(args); - } + internal static IEnumerable GetNamedRanges(string fileName, string worksheetName, ExcelQueryArgs origArgs) + { + var args = new ExcelQueryArgs(origArgs); + args.FileName = fileName; + args.WorksheetName = worksheetName; + args.ReadOnly = true; + return GetNamedRanges(args); + } - internal static IEnumerable GetNamedRanges(ExcelQueryArgs args) - { - var namedRanges = new List(); - - var conn = GetConnection(args); - try - { - if (conn.State == ConnectionState.Closed) - conn.Open(); - - var excelTables = conn.GetOleDbSchemaTable( - OleDbSchemaGuid.Tables, - new Object[] { null, null, null, "TABLE" }); - - namedRanges.AddRange( - from DataRow row in excelTables.Rows - where IsNamedRange(row) - && (!string.IsNullOrEmpty(args.WorksheetName) ? row["TABLE_NAME"].ToString().StartsWith(args.WorksheetName) : !IsWorkseetScopedNamedRange(row)) - let tableName = row["TABLE_NAME"].ToString() - .Replace("''", "'") - where IsNotBuiltinTable(tableName) - select tableName.Split('$').Last()); - - excelTables.Dispose(); - } - finally - { - if (!args.UsePersistentConnection) - conn.Dispose(); - } - - return namedRanges; - } + internal static IEnumerable GetNamedRanges(ExcelQueryArgs args) + { + var namedRanges = new List(); + + var conn = GetConnection(args); + try + { + if (conn.State == ConnectionState.Closed) + conn.Open(); + + var excelTables = conn.GetOleDbSchemaTable( + OleDbSchemaGuid.Tables, + new Object[] { null, null, null, "TABLE" }); + + namedRanges.AddRange( + from DataRow row in excelTables.Rows + where IsNamedRange(row) + && (!string.IsNullOrEmpty(args.WorksheetName) ? row["TABLE_NAME"].ToString().StartsWith(args.WorksheetName) : !IsWorkseetScopedNamedRange(row)) + let tableName = row["TABLE_NAME"].ToString() + .Replace("''", "'") + where IsNotBuiltinTable(tableName) + select tableName.Split('$').Last()); + + excelTables.Dispose(); + } + finally + { + if (!args.UsePersistentConnection) + conn.Dispose(); + } + + return namedRanges; + } - public static string ColumnIndexToExcelColumnName(int index) - { - if (index < 1) throw new ArgumentException("Index should be a positive integer"); - var quotient = (--index) / 26; - - if (quotient > 0) - { - return ColumnIndexToExcelColumnName(quotient) + (char)((index % 26) + 65); - } - else - - { - return ((char)((index % 26) + 65)).ToString(); - } - } + public static string ColumnIndexToExcelColumnName(int index) + { + if (index < 1) throw new ArgumentException("Index should be a positive integer"); + var quotient = (--index) / 26; + + if (quotient > 0) + { + return ColumnIndexToExcelColumnName(quotient) + (char)((index % 26) + 65); + } + else + + { + return ((char)((index % 26) + 65)).ToString(); + } + } + + internal static DatabaseEngine DefaultDatabaseEngine() + { + return Is64BitProcess() ? DatabaseEngine.Ace2016 : DatabaseEngine.Jet; + } + internal static bool Is64BitProcess() + { + return (IntPtr.Size == 8); } + + } }