In Excel VBA (or if you could in C#, I'm using the Excels Object Library from .NET), how to copy a worksheet from one workbook to another sheet in another workbook. Basically, what I'm doing is copying every of my sheet into a central worksheet in another workbook and then will do all the stuff I need to do there. I tried using Range.Copy method, I gave the Destination parameter as the range of the other workbook. It worked perfectly, but there is one problem, that is every time I copy it replaces the older data in that worksheet. How do I do something like so that when I paste it pastes in the end of the sheet.
EDIT: I searched and found a way, but now when I copy the cells I get a COM exception with the message "To paste all cells from an Excel worksheet into the current worksheet, you must paste into the first cell (A1 or R1C1)."
Following is the code, it is in C#
logWorksheet = logWorkbook.ActiveSheet as Excel.Worksheet;
Excel.Range tempRange = logWorksheet.Cells[logWorksheet.Rows.Count, "A"] as Excel.Range;
tempRange = tempRange.get_End(Excel.XlDirection.xlUp);
int emptyRow;
if (tempRange.Row > 1)
emptyRow = tempRange.Row + 1;
else
emptyRow = tempRange.Row;
string copyLocationAddress = Convert.ToString(emptyRow);
Excel.Range copyLocation = logWorksheet.get_Range(
"A" + copyLocationAddress, Type.Missing) as Excel.Range;
// copy whole workbook to the central workbook
tempLogSheet.Cells.Copy(copyLocation);
-- UPDATE --
This snippet copies the cells A1:A3 of Book1 to Book2. It will find the last used cell in Book2 and will append the data underneath it.
Sub CopyRange()
Dim source As Worksheet
Dim destination As Worksheet
Dim emptyRow As Long
Set source = Workbooks("Book1.xlsx").Sheets("Sheet1")
Set destination = Workbooks("Book2.xlsx").Sheets("Sheet1")
'find empty row (actually cell in Column A)'
emptyRow = destination.Cells(destination.Rows.Count, 1).End(xlUp).Row
If emptyRow > 1 Then
emptyRow = emptyRow + 1
End If
source.Range("A1:A3").Copy destination.Cells(emptyRow, 1)
End Sub
-- OLD --
This sample copies all the sheets of Book1.xlsx to Book2.xlsx:
Workbooks("Book1.xlsx").Worksheets.Copy Before:=Workbooks("Book2.xlsx").Sheets(1)
Related
I have written C# application using Excel Interop 12.0 that worked fine on Excel 2007 and Excel 2010. But it is working randomly on Excel 2016. It gives Activate method of Range class failed error sometimes. When I rerun the program it is ok. Again I run it throws error. The program opens about 30 workbooks and populates the workbook from C#. I use Range.get_ReSize() and Range.Activate() in many places. Why is the behavior random? Any Help is appreciated
xlWb.Activate();
xlWsSummary.Activate();
Excel.Range ra = xlWsSummary.UsedRange;//append to the last cell in the used range ra.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, System.Type.Missing).Activate();
Excel.Range Range;
string cellToPaste = "A" + (xlApp.ActiveCell.Row + 1).ToString();//go to the next row
Range = xlWsSummary.get_Range(cellToPaste, System.Type.Missing);
Range = Range.get_Resize(1, index);
Range.Value2 = data;
Range.Font.Size = 8;//set the fontsize ```
I'm not sure if this is what you're looking for exactly, but here is some sample code that works through 2 Excel workbooks, each with a single worksheet containing 6 numbers:
A B C
----------
1 | 3 4 5
2 | 6 7 8
This data is copied from each workbook and appended to data in a summary workbook, creating:
A B C
----------
1 | 3 4 5
2 | 6 7 8
3 | 3 4 5
4 | 6 7 8
Finally, the next 'A' column cell after the data is selected before saving the summary workbook:
string file = #"C:\Users\me\Desktop\Summary.xlsx";
List<string> fileData = new List<string>{#"C:\Users\me\Desktop\Book1.xlsx",
#"C:\Users\me\Desktop\Book2.xlsx"};
Excel.Application xlApp = new Excel.Application();
// Open summary workbook and init data workbook and worksheet
Excel.Workbook xlWb = xlApp.Workbooks.Open(file);
Excel.Worksheet xlWsSummary = xlWb.Sheets[1];
Excel.Workbook xlWbData = null;
Excel.Worksheet xlWsData = null;
// Work through your data workbooks
for ( int i = 0; i < fileData.Count; i++ )
{
// Open data workbook
xlWbData = xlApp.Workbooks.Open(fileData[i]);
xlWsData = xlWbData.Sheets[1];
// Get specific range of data. I didn't use UsedRange in case only a subset of data is required
string dataStart = "A1";
string dataEnd = "C2";
Excel.Range rangeSource = xlWsData.get_Range(dataStart, dataEnd);
// Determine next available 'A' cell after used range in summary worksheet
Excel.Range ra = xlWsSummary.UsedRange;
Excel.Range rangeDest = ra.get_Range("A" + (ra.Rows.Count + 1));
// Copy data from data workbook to summary workbook
rangeSource.Copy(rangeDest);
// Select the range just copied to the summary workbook and format as required
Excel.Range rangeFormat = rangeDest.Resize[rangeSource.Rows.Count, rangeSource.Columns.Count];
rangeFormat.Font.Size = 8;//set the fontsize ```
}
// Release data workbook objects and close before doing anything else
Marshal.ReleaseComObject(xlWsData);
xlWbData.Close();
Marshal.ReleaseComObject(xlWbData);
// Select next available cell in A column
xlWsSummary.Activate();
Excel.Range used = xlWsSummary.UsedRange;
Excel.Range next = xlWsSummary.get_Range("A" + (used.Rows.Count + 1));
next.Select();
// Save the file
xlWb.SaveAs(file);
// And, release!
Marshal.ReleaseComObject(xlWsSummary);
xlWb.Close();
Marshal.ReleaseComObject(xlWb);
I may have not handled the Excel object releasing properly so you'd better look into that and the Activate() call gives an ambiguity warning but otherwise, hope this helps.
I am reading excel file using XSSF. while reading excel sheet by row
wise if the empty cell is present in the row it tends to skip that cell value and
auto populate it with next column which gives me the wrong output. what need to be change in the program to read the row exactly what
is there in the excel including blank cell values.Below is my sample code.
XSSFWorkbook wb = new XSSFWorkbook(file);;
XSSFSheet ws =(XSSFSheet)wb.GetSheetAt(0);
for (i = 1; i <= ws.LastRowNum; i++)
{
XSSFRow row = (XSSFRow)ws.GetRow(i);//the code where empty cells are skipping
}
I have an Excel worksheet with some data. I also have a List of the column headers of the worksheet. The headers in the list are in a different order than the headers in the worksheet, and I need to reorder the Excel worksheet's columns to be the same order as the list.
List<string> dataset1Variables = new List<string>() { "Variable1", "Variable2", "Variable3", "Variable4" };
The headers of my Excel sheet may look like this:
Variable 3 | Variable 1 | Variable 4 | Variable 2
I have come across this code to shift columns but this is only for moving 1 column to a specific location. The list might be completely mixed up so I would need to shift many columns.
Excel.Range copyRange = xlWs.Range["C:C"];
Excel.Range insertRange = xlWs.Range["A:A"];
insertRange.Insert(Excel.XlInsertShiftDirection.xlShiftToRight,
copyRange.Cut());
What would be the best approach for doing this? Preferably using Interop.
If you have an empty row right above your worksheet with data, you can add matching formula right above headers. In below assuming your list is on Sheet2 range B2:B5 and your data headers start on Sheet1 range A2:D2
Excel.Workbook myBook = xlApp.Workbooks.Open(#"path\excel.xlsx");
Excel.Worksheet ws = myBook.Worksheets[1];
// You can use all dynamic ranges instead
// Excel.Range xlRng = ws.Range[ws.Cells[yourRow, firsColumn], ws.Cells[yourRow, lastColumn]];
Excel.Range xlRng = ws.Range[ws.Cells[1, 1], ws.Cells[1, 4]]; // ws.Range["A1:D1"];
xlRng.FormulaR1C1 = "=MATCH(R[-1]C,Sheet2!R2C2:$R5C2,0)";
// Below is how you can get full address for your list if it's in different workbook and replace Sheet2!R2C2:$R5C2 with rangeFullAddress
// string rangeFullAddress = xlRng.Address[true,true,Excel.XlReferenceStyle.xlR1C1,true];
xlRng.Calculate();
xlRng.Value = xlRng.Value;
After this you can just sort your data using Excel Sort by 1st row. After sorting your 1st row it would look like this: 1, 2, 3, 4. Then clear data on 1st row ws.Range["A1:D1"].Clear();.
Your sort key would be Key1: ws.Range["A1:D1"], here is c# sort example using c# to sort a column in excel only change Excel.XlSortOrientation and adjust for your range.
There are other ways to sort but this way you'll keep individual formats, comments of each cell within your data
I missed 1 important detail - that your list is not in Excel sheet, but you can add it to Excel, perhaps in temporary workbook or right on the same sheet:
object [,] columnHeaders = new object[3,0]; // or object[0,3]; if you'd like to add into 1 row
columnHeaders[0, 0] = "Variable1";
columnHeaders[1, 0] = "Variable2";
columnHeaders[2, 0] = "Variable3";
columnHeaders[3, 0] = "Variable4";
xlRng.FormulaR1C1 = columnHeaders; // xlRng would be in the above Sheet2!R2C2:$R5C2
I have a Word.Chart whose underlying worksheet I am populating with data from C#.
My problem is however, that the selected dataset in the worksheet contains just the default selection (eg. 5x4 cells or sg like that), and not ALL the data which I entered.
If the object were an Excel chart, I could do
Excel.Range rangeBegin = ws.Cells[1, 1];
Excel.Range rangeEnd = ws.Cells[xAxisContents.Count + 1, feeds.Count + 1];
Excel.Range chartRange = ws.get_Range(rangeBegin, rangeEnd);
wordChart.SetSourceData(chartRange);
However, the Word.Chart's SetSourceData method only accepts a string, and if I call it with an arbitrary range (just for testing), eg. wordChart.SetSourceData("A1:C3"), it fails with a ComException(E_FAIL).
I have also found this code on a Microsoft blog:
Excel.Range tblRng = dataSheet.get_Range("A1", "B5");
Excel.ListObject tbl = dataSheet.ListObjects["Table1"];
tbl.Resize(tblRng);
which I think is meant to resize the selected dataset to the size of the worksheet. This would also be perfect for me, however, "Table1" is reported as an unknown index (maybe because I am using a non-English version of Word.)
What should I do to select the appropriate dataset?
I am using Excel Interop to generate Excel Table into an xlsx file. I have a very simple table with 3 columns and no header, no totals but has 2 rows.
Now when I generate the Excel file, I use the following code
...
Range rng = worksheet.Range["$A$1:$C$2"];
ListObject lo = worksheet.ListObjects.Add(xlSrcRange, rng, Type.Missing, XlYesNoGuess.xlNo);
lo.ShowHeaders = false;
...
With the above code it generates the table with cell range A2:C3 instead of A1:C2. But any values I set in the A row are set but outside of the table.
If I set the ShowHeaders to true in the 3rd line of code above, then Excel is converting the top row as the header line and still moves the table cell range to A2:C3
Am I doing something wrong? I appreciate any and all help and guidance to fix this issue.
Thanks
Jaideep
Try this
//
//~~> Rest of your code
//
Range rng = worksheet.Range["$A$1:$C$2"];
ListObject lo = worksheet.ListObjects.Add(xlSrcRange, rng, Type.Missing, XlYesNoGuess.xlNo);
lo.ShowHeaders = false;
Excel.Range rngRowOne = worksheet.get_Range("A1", "A1");
rngRowOne.EntireRow.Delete(Excel.XlDirection.xlUp);
//
//~~> Rest of your code
//