I keep looking for examples on how to add a radio button to an Excel worksheet programmatically but cannot get a straight answer. I've tried using Microsoft.Office.Interop.Excel and Microsoft.Office.Tools.Excel but neither have worked. The system I am working on already has Microsoft.Office.Interop.Excel as a reference so unless there are any objections to using this assembly, this would be my preference.
//propertyWorkSheet is a Microsoft.Office.Interop.Excel worksheet
Microsoft.Office.Tools.Excel.Application xlApp = new Excel.Application();
Microsoft.Office.Tools.Excel.Worksheet worksheet = (Microsoft.Office.Tools.Excel.Worksheet)propertyWorksheet;
Microsoft.Office.Tools.Excel.Range selection = worksheet.get_Range("A12:A12", "A12:A12");
Microsoft.Office.Tools.Excel.Controls.Button button = new Microsoft.Office.Tools.Excel.Controls.Button();
worksheet.Controls.AddControl(button, selection, "Button");
Did some more digging and got to this with my code and it worked.
Microsoft.Office.Interop.Excel.Buttons buttons = propertyWorksheet.Buttons(System.Reflection.Missing.Value) as Microsoft.Office.Interop.Excel.Buttons;
Microsoft.Office.Interop.Excel.Button button = buttons.Add(33, 33, 33, 33);
button.Caption = "Test BUTTON";
Related
I made an excel file in C# and saved it automatically.
If dragging the excel file to an already opened excel .. It opens very well and I can edit it right away.
But If excel is turned off and I open the file with double click,
the file is open and its contents are visible, but the mouse is infinitely loaded and cannot be edited.
(In the meantime, with the mouse wheel, the up/down window can be moved. just it.)
How can I solve it about infinite loading even if I open it?
Excel.Application excelApp = null;
Excel.Workbook wb;
Excel.Worksheet ws1;
excelApp = new Excel.Application();
excelApp.WindowState = Excel.XlWindowState.xlMaximized;
excelApp.Visible = true;
excelApp.Interactive = false;
wb = excelApp.Workbooks.Add();
ws1 = excelApp.ActiveSheet;
excelApp.DisplayAlerts = false;
wb.SaveAs(#filePath+Name+".xlsx", Excel.XlFileFormat.xlWorkbookDefault);
[contents about Cell value, and making template]
excelApp.Interactive = true;
ws1.Activate();
wb.Save();
Marshal.ReleaseComObject(excelApp);
Marshal.ReleaseComObject(wb);
Marshal.ReleaseComObject(ws1);
GC.Collect();
I am using C# windows application for Excel data add/update. I had added Microsoft.Office.Interop.Excel reference(Reference -> Right Click -> Add Reference -> COM -> Type Libraries -> Microsoft Excel 1X.0 Object Libraries). On my form, I have one panel control panel1, one List-box lstSamples and two button btnAddSample, btnFormatWorksheet.
My sample code is as below:
using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public partial class Form1 : Form
{
Microsoft.Office.Interop.Excel.Application excelApp;
Workbook excelWorkBook;
Worksheet excelWorkSheet;
public Form1()
{
InitializeComponent();
LoadExcelFile();
}
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
private void LoadExcelFile()
{
excelApp = new Microsoft.Office.Interop.Excel.Application();
excelApp.Visible = true;
excelApp.ScreenUpdating = true;
excelApp.EnableAutoComplete = false;
excelWorkBook = excelApp.Workbooks.Add(XlWBATemplate.xlWBATWorksheet);
IntPtr excelHwnd = new IntPtr(excelApp.Application.Hwnd);
SetParent(excelHwnd, panel1.Handle);
}
private void btnAddSample_Click(object sender, EventArgs e)
{
excelWorkSheet = (Worksheet)excelWorkBook.Worksheets.get_Item(1);
int lastUsedRow = excelWorkSheet.UsedRange.Rows.Count;
excelWorkSheet.Cells[lastUsedRow + 1, 1] = lstSamples.SelectedItem.ToString();
lstSamples.Items.Remove(lstSamples.SelectedItem);
}
private void btnFormatWorksheet_Click(object sender, EventArgs e)
{
Range chartRange;
excelWorkSheet = (Worksheet)excelWorkBook.Worksheets.get_Item(1);
chartRange = excelWorkSheet.get_Range("b2", "e9");
chartRange.BorderAround(XlLineStyle.xlContinuous,
XlBorderWeight.xlMedium, XlColorIndex.xlColorIndexAutomatic,
XlColorIndex.xlColorIndexAutomatic);
}
}
Please follow the steps as I mentioned 1. Run the application and add data in "A1" cell (Which is of string type) 2. Again add some data in "A2" cell and Press enter 3. Select one item from lstSamples listbox and click on btnAddSample (Result is like selected item will get added into "A3" cell 4. Try to modify "A1" or "A2" cell data. (Here lstSample is having items of string type like Test1, Test2, Test3,....). If you are able to edit cells then click on btnFormatWorksheet then try to edit any cell.
Why are you referencing the COM DLL? You should be referencing the .Net PIA's - the Primary Interop Assemblies in this location, via the .Net tab in the References window and browse to:
C:\Program Files (x86)\Microsoft Visual Studio [version]\Visual Studio Tools for Office\PIA\Office[version]\Microsoft.Office.Interop.Excel.dll
Only for unit testing do you reference the COM one. See my answer here and how I originally worked it out. It's easy to get confused because in Solution Explorer they are both called the same thing!
If that doesn't work, I originally put this as an answer to save other peoples time being wasted.
Both Ahmed and I cannot reproduce the problem you described with the code you have provided.
See I typed in cells A1 and A2, then I selected an item in the list and clicked the button. Then I select the cell A2 and type Editable.
ps If you can provide the steps to reproduce I'll be happy to take another look at it.
UPDATE:
Your revised steps to reproduce the problem are incorrect, it works for me:
UPDATE 2:
Check if the message pump filters are causing the focus to go to another cell/control:
Excel CustomTaskPane with WebBrowser control - keyboard/focus issues
Let's create a ListObject and attach an event on it as msdn explain here: https://msdn.microsoft.com/en-us/library/eyfs6478.aspx
The code
In an application-level addin, code will look like above:
Worksheet worksheet = Globals.Factory.GetVstoObject(Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]);
Excel.Range cell = worksheet.Range["$A$1:$D$4"];
ListObject list1 = worksheet.Controls.AddListObject(cell, "list1");
list1.Selected += list1_SelectedDeselected;
list1.Deselected += list1_SelectedDeselected;
With something like that to see the triggered events :
private void list1_SelectedDeselected(Excel.Range Target)
{
Worksheet worksheet = Globals.Factory.GetVstoObject(Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]);
Excel.Range cell = worksheet.Range["$A$6"];
if (cell.Value2 == "foo")
{
cell.Value2 = "bar";
}
else
{
cell.Value2 = "foo";
}
}
Strange behavior
If you run this code within a add-in in excel, you'll see this and that
If you cut/paste this table within the same worksheet, every attached events will be triggered.
But if you cut/paste into another sheet, the events will not be attached anymore to the ListObject.
Are there a reason I don't know for this unpredictable behavior?
You need to use another VSTO object to subscribe to the events anew. The GetVstoObject should be used to get a new Worksheet object.
I'm trying to create a simple example with #officewriter #excelwriter and having trouble using the styles. Not sure why.
ExcelApplication XLAPP = new ExcelApplication();
Workbook WB = XLAPP.Create();
Worksheet WKST = WB.Worksheets[0];
DataSet ds = <...some valid dataset with 2 columns....>
DataView dv = ds.Tables[0].DefaultView;
DataImportProperties props = WB.CreateDataImportProperties();
SoftArtisans.OfficeWriter.ExcelWriter.Style dataStyle = WB.CreateStyle();
props.UseColumnNames = true;
dataStyle.BackgroundColor = Color.SystemColor.Red;
dataStyle.CellLocked = true;
Area importArea = WKST.ImportData(dv, WKST.Cells[0, 0],props);
importArea.ApplyStyle(dataStyle);
XLAPP.Save(WB, Page.Response, "Output.xls", false);
Here's the problem: the color style works in the output but the CellLocked style does not. Why?
Thanks for any help. Frustrated - I thought this was a simple example!
ExcelWriter is designed to mimic Excel, so usually the steps that you need to take in Excel to active certain properties are the same steps that you need to take in ExcelWriter.
In Excel, all the cells in a worksheet have the locked style property set, but that property will not take effect until the worksheet is protected. (Right click on a cell and go to Format Cells > Protection - the Locked property is checked, but the cells are not locked until you go to Review > Protect Sheet).
Similarly, in ExcelWriter, all the cells in Worksheet.Cells have the Style.CellLocked set to true by default, but that property will not take effect until Worksheet.Protect() is called. Once you protect the sheet, the cells should be locked.
ExcelApplication xlapp = new ExcelApplication();
Workbook wb = xlapp.Create(ExcelApplication.FileFormat.Xlsx);
Worksheet ws = wb.Worksheets["Sheet1"];
//Currently, all the cells have default "locked" style set to true
//Protecting the worksheet will activate this property
ws.Protect("MyPassword");
xlapp.Save(wb, "ProtectedWorksheet.xlsx");
Since all the cells default to Locked, if you want to lock only an area of cells and not the entire worksheet, you will need to set Style.CellLocked to false on any cells that you want to leave unlocked. When the worksheet is protected, these cells will remain editable.
ExcelApplication xlapp = new ExcelApplication();
Workbook wb = xlapp.Open("MyWorkbook.xlsx");
Worksheet ws = wb.Worksheets[0];
//Create a style that will leave certain cells unlocked
//when the worksheet is protected
Style unlockStyle = wb.CreateStyle();
unlockStyle.CellLocked = false;
//Select the area that will be left unprotected
//Apply the style to that area
Area unlockedArea = ws.PopulatedCells;
unlockedArea.ApplyStyle(unlockStyle);
//Protect the worksheet
ws.Protect("MyPassword");
xlapp.Save(wb, "MyNewWorkbook.xlsx");
For more about protecting worksheets, we have a guide in our documentation: Protecting Your Worksheet.
Note: I work for SoftArtisans, makers of OfficeWriter.
I created a new Excel file with C#.
When I open the document all the worksheets are align right to left.
How can I align the worksheet/workbook/window to display left to right grammatically?
Sub leftToRight()
Application.DefaultSheetDirection = xlLTR
ActiveSheet.DisplayRightToLeft = False
End Sub
You can also change the setting through Tools->Options->International. Note that you need to set/unset the Checkbox "View current sheet right-to-left" to change currently open sheets.
Edit: Sorry I accidentally interpreted your question as VBA.
Here is a c# Solution:
Excel.Application xlApp = new Excel.Application();
xlApp.Visible = true;
xlApp.Workbooks.Add(System.Type.Missing);
Excel.Worksheet active = (Excel.Worksheet)xlApp.ActiveSheet;
xlApp.DefaultSheetDirection = (int)Excel.Constants.xlLTR; //or xlRTL
active.DisplayRightToLeft = false;
I would like to introduce my implementation of this feature after i used marg concept and changed it to the right syntax for me:
public void SetWorksheetDirection(Application excel, bool isRTL)
{
Worksheet active = (Worksheet)excel.ActiveSheet;
if (isRTL)
excel.DefaultSheetDirection = (int)XlDirection.xlToRight;
else
excel.DefaultSheetDirection = (int)XlDirection.xlToLeft;
active.DisplayRightToLeft = isRTL;
}
Do this one time to change the default direction:
Alt+F11 to open the VBA editor
Ctrl+G to open the Immediate window
in the Immediate window type Application.DefaultSheetDirection = xlLTR and press Enter
Alt+Q to close the VBA editor
create a new workbook to test it
If you just wanted to organize some of the columns, you could use a line like this:
oWS.Range["A1:B2000"].HorizontalAlignment = Microsoft.Office.Interop.Excel.Constants.xlLeft;