Excel Interop right to left document - c#

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;

Related

Microsoft.Office.Interop.Excel add radio button to worksheet

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";

C# Excel add-in worksheet error 0x800A03EC - unrequested cell movement

Alrighty guys I have rather a brain mangler for you; I'm trying develop a relatively simple add-in for excel that should read in data from Sheet A in a workbook, create a new or update sheet B to contain a simplified version of said data in sheet A at the press of a button. Below is some example code I'm working on:
Application.SendKeys("{ENTER}"); // Exit edit mode
Excel.Workbook wb = this.Application.ActiveWorkbook;
Excel.Worksheet sheetA = null;
Excel.Worksheet sheetB = null;
foreach (Excel.Worksheet sheet in wb.Worksheets) {
// Assume origin sheet we want to move from is same name as book name
if (sheet.Name == wb.Name)
sheetA = sheet;
// Sheet to move to will be called review. Clean if it exists.
else if (sheet.Name == "Review")
{
sheetB = sheet;
sheetB.Cells.ClearContents();
}
}
// If origin sheet cannot be found, assume it's the first sheet
if (sheetA == null)
sheetA = (Excel.Worksheet)wb.Worksheets[1];
// Add the review sheet after the origin sheet if it doesn't exist
if (sheetB == null)
{
sheetB = wb.Worksheets.Add(After: sheetA);
sheetB.Name = "Review";
}
// Simply copy across the value of the first cell
sheetB.Range["A1"].Value2 = sheetA.Range["A1"].Value2;
Now the outcomes of this code seem to be radically different depending on whether anything is in "edit mode" (cells are being edited) or not. If not, all is well as you'd expect, a new sheet is created in the correct position and the cell populated.
If a cell is being edited though, the edited cell is moved to another worksheet in the workbook. If there is no other sheet to move to a COMException with HRESULT: 0x800A03EC is thrown (error unknown).
This error shows up A LOT and it's really frustrating with it essentially telling you "be damned if I know", so any ideas would be appreciated. The most common thing seems to be "worksheet doesn't exist" which would be the case here, but I can't tell why it wants to move the edited cell in the first place?
Solution found. Simulating a return key stroke (first line of my example) does exit edit mode, but a delay is required for the application to process it. My implementation worked out as:
Application.SendKeys("{ENTER}"); // Exit edit mode
Timer timer = new Timer(100); // 100ms delay
timer.AutoReset = false; // Stop the timer looping and re-executing
timer.Elapsed += new ElapsedEventHandler((Sender, ent) =>
{
// Code you want to execute outside of edit mode
});
timer.Start(); // Start her up!
Hope that helps some lost wandering soul!

ExcelWriter.Style CellLocked - why won't it work?

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.

Setting ViewSheetSetting.InSession.Views Property

Has anyone worked with setting the InSession.Views property?
The problem I have is that when I set the following property immediately after opening a document it doesn't work (i.e. the Views size is still 0 even though the viewSet has 4 items).
revitDocument.PrintManager.ViewSheetSetting.InSession.Views = viewSet;
but after modifying the In-Session view/sheet set using print dialog in revit, then I can assign to it.
does anyone know why?
Revit stores the current view sheet set in the variable Document.PrintManager.ViewSheetSetting.CurrentViewSheetSet and that's what it's really using . At the beginning when you are setting the InSession you should be setting the CurrentViewSheetSet instead. The reason that it is working after using the print dialog is that it is setting the CurrentViewSheetSet to InSession. What I would do is to create a temporary ViewSheetSetting on document open and then delete it when the document closes. Below is some of the code that I used though with mine I only kept the ViewSheetSetting for the scope of a single function call instead of from document open to document close.
For Open
const string tempoarySheetSetSettingName = "Temp Sheet Set";
ViewSheetSetting viewSheetSetting = _printManager.ViewSheetSetting;
//Save your temporary sheet set
_printManager.ViewSheetSetting.SaveAs(tempoarySheetSetSettingName);
ViewSheetSet selected = null;
FilteredElementCollector viewCollector = new FilteredElementCollector(document);
viewCollector.OfClass(typeof(ViewSheetSet));
//Find the sheet set that you just created
foreach (ViewSheetSet set in viewCollector.ToElements())
{
if (String.Compare(set.Name, tempoarySheetSetSettingName) == 0)
{
selected = set;
break;
}
}
//Set the current view sheet set to the one that you just created
viewSheetSetting.CurrentViewSheetSet = selected;
//Set the views to which ever set you would like to print
viewSheetSetting.CurrentViewSheetSet.Views = viewSetToPrint;
viewSheetSetting.Save();
For Printing
Your user will need to select the temporary view set that you created whenever they print.
For Close
_printManager.ViewSheetSetting.Delete();
In Revit 2015 using VB.Net I couldn't force this ViewSheetSet Colletor to work like this:
Dim VSSCollector As New FilteredElementCollector(curDoc)
VSSCollector.OfClass(oftype(ViewSheetSet))
Instead I used this and it worked:
Dim VSSCollector As New FilteredElementCollector(curDoc)
VSSCollector.OfClass(GetType(ViewSheetSet))

Adding formula to Excel with C# - making the formula shown

I wanted to add formulas to an Excel workSheet.
I managed to do so with the Formula property.
The problem is that when I open the worksheet in Excel, I can see that the formula works - but I can only see the result in the cell. I can't see the formula that was calculated in the Formula Bar at the top of Excel.
Obviously if I enter a formula in Excel itself I can see the result in the cell and the formula in the Formula Bar.
Some of my code:
for (int i = 0; i < nOfColumns / 3; i++)
{
Range cells = workSheet.Range[workSheet.Cells[2, i * 3 + 3], workSheet.Cells[lastRowNumber, i * 3 + 3]];
cells.FormulaR1C1 = "=IF(EXACT(RC[-2],RC[-1]),TRUE,ABS(RC[-2]/RC[-1]-1))";
}
below is a test code. even after I save the workbook - the FormulaHidden is false and I can successfully retrieve the formula insterted. really frustrated
Microsoft.Office.Interop.Excel.Application excelApp = null;
Workbooks workBooks = null;
Workbook workBook = null;
Worksheet workSheet;
try
{
excelApp = new Microsoft.Office.Interop.Excel.Application();
excelApp.DisplayAlerts = false;
workBooks = excelApp.Workbooks;
workBook = workBooks.Open(filePath, AddToMru: false);
workSheet = workBook.Worksheets.get_Item(1);
int nOfColumns = workSheet.UsedRange.Columns.Count;
int lastRowNumber = workSheet.UsedRange.Rows.Count;
Range rng = workSheet.Range["C1"];
rng.Formula = "=SUM(B2:B4)";
String formula = rng.Formula; //retrieve the formula successfully
rng.FormulaHidden = false;
workSheet.Unprotect();
workBook.SaveAs(filePath, AccessMode: XlSaveAsAccessMode.xlExclusive);
formula = rng.Formula; //retrieve the formula successfully
bool hidden = rng.FormulaHidden;
}
catch (Exception e)
{
throw;
}
finally
{
if (workBook != null)
{
workBook.Close();
workBook = null;
}
if (workBooks != null)
{
workBooks.Close();
workBooks = null;
}
if (excelApp != null)
{
excelApp.Quit();
excelApp = null;
}
}
}
Anyone know how to make the formula shown, when adding the formulas programatically ?
finally !!! figured it out. this behavior is caused by the SaveAs flags.
changed
workBook.SaveAs(filePath, AccessMode: XlSaveAsAccessMode.xlExclusive);
to
workBook.SaveAs(filePath, AccessMode: XlSaveAsAccessMode.xlShared);
now the only thing left is to understand what exactly is the different between the two flags. :)
Hiding the formula (by checking Hidden checkbox on Format Cells dialog) & protecting the worksheet (thereafter) will cause the formula to not show in the formula bar.
Example VBA code
Range("C1").FormulaHidden = True 'set this property to false to make formula visible.
Sheet1.Protect
EDIT: In order to see the formula in the formula bar
Range("C1").FormulaHidden = False
Sheet1.Unprotect
Go to the Formula tab on the tool bar, and click "Show Formulas".
I think localization could be involved in this weird behaviour.
Some time ago, working in Excel, I had the impression that formulas got stored in localized language (I was using italian), then undergo a conversion when compiled. This could make sense, because localized constants are an essential part of the spreadsheet data.
I'm sorry I haven't now Excel available, so I can't be more precise, but I think you could try to localize to english your spreadsheet, or set the formula text in your local language.

Categories

Resources