Is it possible to set foreign key between two excel sheets? - c#

Is it possible to set foreign key between two excel sheets and query records from the two sheets?
I got an excel sheet of Student Details and another sheet consists of the total marks. Fields common to both the sheet is the RegID. I need to display the Name and Marks from the two sheets on a grid...How can it be done? please help....
Query = "SELECT Status from [Viewer$] as a LEFT JOIN [UI$] as b ON a.[Responsible Person] = b.[Responsible Person] where b.[Responsible Person] = null" ;
This query is not returning the records to a dataset...

If you mean to read Data from two Sheets and mix it to make "combined" records which you enter in the Database where you have the FK set then it should be possible.
Read Reading Excel Cells using C#
You can open who sheets which you access in a Loop, but you will have to coordinate the Data building from your sheets.

NewBie,
I've used the excel 2007 openxml sdk (DocumentFormat.OpenXml) to great effect in this scenario. It's basically a LINQ library that takes the excel docs into objects and allows you to query inside c# just like any other LINQ object. Microsoft actually do have (after a quick search) a pretty good 'idiots guide' on this topic. You can find it here:
[edit] - added a few more links
http://msdn.microsoft.com/en-us/library/dd920313%28v=office.12%29.aspx
http://blogs.msdn.com/b/johnrdurant/archive/2010/02/19/excel-open-xml-linq-part-i.aspx
http://www.briankeating.net/blog/post/2010/04/26/Linq-to-Xlsx.aspx
if you use LINQ, it's a no brainer and is definately the only way that I would go with this type of task. It will also 'cater' for you idea of fk's as it will allow you to 'join' on any arbitary field that you care to define (i.e. as with any LINQ query), thus it should address your requirement perfectly.

Not possible using SQL. Neither UNIQUE nor FOREIGN KEY is supported where the data source is an Excel workbook.

Related

How to extract a table with DocX?

I'm extracting text out of an MS Word document (.docx). I'm using the DocX C# library for this purpose, which works in general quit well. No, I want to be able to extract tables. The main problem is, that if I'm looping through the paragraphs, I can get whether I'm in a table cell with:
ParentContainer == Cell
but I do not get any information about how many rows and cells. Second possibility which I see is that there is a list with tables as property of the document object. There I can see, how many rows / columns and so on - but I do not know where they are.
Does anyone has an idea how to deal with tables correctly? Any other solution would be appreciated as well :)
I figured it out. The trick is, to check whether each paragraph is followed by a table. This can be done by
...
if (paragraph.FollowingTable != null)
{
tableId = paragraph.FollowingTable.Index;
}
...
The FollowingTable.Index will give you an index to the table, with which you can get all details about the table in the Document.Tables list.

ClosedXML Adding Data to Existing Table

With ClosedXML I am trying to add data to an existing Excel Sheet In an Existing Table. The easy thing to do is to add a table to an excel sheet below is a quick example of how to do that. What I don't understand is if you already have a Table there that is empty how can you just add to the existing table?
// Add a DataTable as a worksheet
wb.Worksheets.Add(dataTable);
I don't know how this question isn't clear to people. If there is an existing Table (created in Excel by going to "Insert -> Table") and you open an Excel document using ClosedXML, adding data to the next row does not automatically expand the Table.
You can expand it prior to adding the data as such:
IXLTables tsTables = thisSheet.Tables;
IXLTable firstTable = tsTables.FirstOrDefault();
if (firstTable != null)
firstTable.InsertRowsBelow(1);
I had a similar requirement, where I needed to insert data into an existing Table, which had a number of data validations / comments / formula built in.
I found that the easiest solution (for me) was to use the Table's ReplaceData call. This is particularly useful if you provide a name for your Table in the Excel worksheet, as that way you can get a reference to the table directly from the workbook, ie:
var candidateTable = workbook.Table("Candidates");
candidateTable.ReplaceData(candidateData, propagateExtraColumns: true);
Note that the key to getting this to work properly is to set the propogateExtraColumns parameter - this will ensure any formula / etc you have set will automatically be copied to any new rows that are created.
FYI - you can set the Excel Table's name by selecting your table in the worksheet, clicking the Design tab, and then entering a table name:
To add a DataTable to an existing worksheet use this:
wb.Worksheet(1).Cell(1, 1).InsertTable(dataTable);
More info in the documentation.

Creating a PivotTable programmatically from multiple database tables

I have a problem with automating Excel that I cannot solve. I want to mimic the "Import External Data" feature. It works already perfectly for flat tables, but not for PivotTables, when I select multiple database tables for the import.
The manual way
I have an Access database with 2 tables (accounts and transactions), linked by a foreign key ("account" in transactions table). I want to import both immediately to a PivotTable. The usual way would be to click on "Data" -> "External Data", then select both tables in the dialog, then choose "PivotTable report" and click "OK". Now the PivotTable is in the active sheet and on the right side there is the Field List which offers all fields in the hierarchy of the imported tables.
This is what I want to mimic for the mentioned database file. Does anyone have an idea how this works?
What I tried
I have already tried to record and adapt a macro, to no avail, as it records incomplete and flawed code. Incomplete because the recorded code does not feature the creation of a data model, but that is obviously necessary (?). Flawed because the code does not run, its syntax is incorrect.
I can successfully create a PivotTable from one database table like this:
Excel.PivotCaches pivotCaches = workbook.PivotCaches();
Excel.PivotCache pivotCache = pivotCaches.Create(Excel.XlPivotTableSourceType.xlExternal,
Type.Missing, Type.Missing);
pivotCache.Connection = conStr;
pivotCache.MaintainConnection = true;
pivotCache.CommandText = "Accounts";
pivotCache.CommandType = Excel.XlCmdType.xlCmdTable;
Excel.PivotTables pivotTables = sheet.PivotTables();
Excel.PivotTable pivotTable = pivotTables.Add(pivotCache, sheet.get_Range("A3", "C20"), "Pivot", Type.Missing, Type.Missing);
But it fails in each of the many attempts I tried to get more than one database table.
What is the way to go for multiple tables?
Bear in mind that I do not necessarily know the table names and the join fields, plus I do not want to lose the distinction between the tables, it should be preserved in the PivotTable field list for hierarchical choice of the fields. Furthermore, a catch-all SQL query would be a serious impairment to performance.
Please help me!
PS: I am on Office 2013 with C# as my language of choice.
/edit1: Later I would also want the PivotTable to refresh if the database tables change (manually invoking that refresh).
/edit2: I would also be entirely satisfied with a way to use multiple worksheets as sources for a PivotTable, as long as they appear separately in the Field List.

C# Linq To Excel Getting Table Data Not Starting In The First Row

I'm developing a MVC 4 web application and one of the requirements is to allow users to upload an excel file which is in a standard format and extract data and save that to a database. I have used linq to excel to read data off of the excel. This works fine provided that the table that I'm extracting data from starts from the first row of the excel sheet.
var details = from c in excel.Worksheet<ContributionScheduleExcelFormat>() select c;
Now my question is how can we still return the same data if say the table headers starts on the third row? Basically some extra information needs to be reflected on the first two rows so that's why my the table in the excel sheet needs to start from the third row now. I believe there is a function already available to get data from a range of cells.
var details = from c in excel.WorksheetRange<ContributionScheduleExcelFormat>(startRange, endRange) select c;
But how would I get the endRange value?
I'm new to linq to excel so please any assistance would be greatly appreciated. Thanks in advance.
For the sake of others that may have this same issue:
Turns out that you can't actually do this at the moment. The only solution is to specify an end range that you know your excel sheet data will not exceed. For example:
var details = from c in excel.WorksheetRange<ContributionScheduleExcelFormat>("A3", "G16000") select c;
It's not pretty at all and personally just looking at it makes me feel uncomfortable but that's the only way right now.

Format as table (TableStyles) in Excel VSTO 2007, error: one table cannot overlap another table

I am making an add-in and I am trying to format the output which my add-in generates,using Format as table table-styles provided by Excel.
The one which you get on the 'home tab' --> 'Format as Table' button on the ribbon.
I am using following code:
SourceRange.Worksheet.ListObjects.Add(XlListObjectSourceType.xlSrcRange,
SourceRange, System.Type.Missing, xlYesNo, System.Type.Missing).Name =
TableName;
SourceRange.Select();
SourceRange.Worksheet.ListObjects[TableName].TableStyle = TableStyleName;
TableStyleName is any style name like TableStyleMedium17, you get it if you just hover a particular style in Excel.
My problem is that, even if I keep the SourceRange as 10 columns, all the columns right till the end get selected and are considered as one table.
Because of that the table I populate right next to it is also considered as a part of the first table that was generated.Since, both the table have same column names excel automatically changes the column names in all the following tables that are generated.
Also, because I am generating the tables in a loop after 2 tables are generated I get the error :
A table cannot overlap another table.
PS: I am clearly mentioning SourceRange as:
var startCell = (Range)worksheet.Cells[startRow, startCol];
var endCell = (Range)worksheet.Cells[endRow, endCol];
var SourceRange = worksheet.get_Range(startCell, endCell);
Kindly suggest a way out.
We were able to figure out what was happening on our end for this:
on the
xlWorkbook.Worksheets.Add([before],[after], Type.Missing, Type.Missing)
call, we had to flip before and after since we wanted the sheets to move right, not left and then accessed
xlWorkbook.Worksheets[sheetCount]
by increasing sheetcount for however many sheets were being generated.
Having it the other way was creating the worksheet to access a previously assigned table formatfrom the SourceRange.Worksheet.ListObjects[TableName].TableStyle = TableStyleName call.
So, I got around this problem a week after posting this, sorry did not update in the rush of things.
This actually is an in built excel functionality.
You cant help it, the excel application will keep doing this.
So, ultimately wrote my own table styles in c# and applied it to the excel range which is mentioned as SourceRange. Its just like writing CSS.
If you are interested in knowing the details of that comment it on this question itself or you can contact me by email from my profile.

Categories

Resources