EPPlus - ExcelWorksheets Class "Add(string Name)" Method trims the worksheet name - epplus

I am using EpPlus (version 3.1.3.0) and observed that, when I add a new worksheet to workbook with a name of 35 char, it trims the name to 31 char.
Do we have any newer version of EPPlus with the fix.

This is an apparently un(der)-documented limitation of Excel, not EPPlus (or even OOXML's SpreadsheetML, based on what I've gleaned from ECMA-376).
See this other SO answer.

Related

Excel VBA UDF autocorrects with wrong case

I have an Excel VBA addin that adds user defined functions (UDFs). These functions all work fine in terms of calculating their results.
I enter them into the Function Wizard using MacroOptions.
When using them in a worksheet, they autocorrect the function names for case. For example, if the function is named MyFunction, and the user enters it as myfunction, then when the formula is entered it autocorrects the function name's case to MyFunction. Just like with Excel's built-in worksheet functions, where if you enter e.g. median it will autocorrect it to MEDIAN.
However, there is one UDF for which that autocorrect is incorrect. I want it to be e.g. MyFunction, but even if the user enters it like that, it autocorrects to all lowercase, myfunction.
I have looked at every relevent line of code and can find no reason for that. The code is the same for all the other UDFs except of course for function name, function description, and the code and parameters in the function itself.
Any idea why that one UDF autocorrects the function name differently?
Here's an example of the MacroOptions line:
Application.MacroOptions "MyAddin.xla!MyFunction", "Description of MyFunction for the Excel's Function Wizard.", , , , , "Custom category in Function Wizard"
And the UDF itself looks like this:
Public Function MyFunction(param1 As Long, param2 As Long) As Long
'MyFunction's code here...
End Function
Again, the UDF calculates correctly. The issue is with the autocorrect on the function name.
I tried closing the addin, then creating a new UDF with the same function name as the affected function in the new, default Excel workbook. It worked correctly -- it autocorrected to the correct case. But when I closed it and went back to the addin, the problem returned.
UPDATE:
Here are the steps that worked for me to fix the problem (thanks, Charles Williams!):
Set the add-in workbook's IsAddin property to false. That turns it into a workbook, so you'll get a worksheet.
File > Save As, save as new xlsm workbook. Important: make sure there are no formulas in the worksheet with the affected function name; otherwise you'll be coming back to this step.
File > Options > Add-ins > Go, Uncheck the add-in so it doesn't load when Excel is started.
Exit and restart Excel.
Open the new xlsm workbook.
Enter a formula with the function name in correct case. It should NOT autocorrect to incorrect case.
Delete the formula.
Save the xlsm workbook.
Make a backup of the original add-in, as you're about to overwrite it.
Save the xlsm as a new xla add-in, overwriting the old one (I assume this works with xlam too but didn't try that).
File > Options > Add-ins > Go, recheck the add-in so it loads when Excel is started.
Restart Excel. Test for the problem; the problem should be fixed.
Excel insists on remembering the capitalization that was used the very first time the UDF is entered into a formula.
I have not found a sensible way of resetting this, apart from renaming the UDF.
If the XLAM's worksheets contain a formula referring to the UDF then that reference will lock in the capitalization. If the XLAM's worksheets do NOT contain a formula referring to the UDF then it will be set from the first workbook that uses it in an Excel session. If you have 2 saved workbooks with different capitalizations and they both get opened then the capitalization in the second gets overwritten with the capitalization from the first.
Inspired by other contributions (thanks!), here are the steps that worked for me:
Close the Excel session and open a new one.
Create a new workbook and write in it a formula including the correctly-capitalized UDF.
Discard the new workbook but keep the Excel session.
Open other workbooks with formulas including the UDF: the UDF will now be correctly capitalized.
You can close the Excel session without saving the workbooks.
In subsequent Excel sessions, the UDF will be correctly capitalized.

Using same VBA code in English and German Excel - Expected Function Or Variable

I've created a vba code in the English version of Excel 2016 for Windows.
I've attempted to run the code in a German version of Excel 2011 and 2016 for Mac but both do not work.
I'm getting an error that the sub function is waiting for a variable or function.
Trying to debug what the real problem, it seems there are three issues:
IFNA() is not a available function in Excel for Mac - so I had it removed.
I'm using INDEX, MATCH functions. MATCH is translated into VERGLEICH in German Excel and so the function is not recognized.
This line of code is also causing problems, seems like Range().Activate or Range().Select is also not recognized.
x = Range("A" & insert_at).Activate
Any ideas or guidance in the last two issues would be very helpful.
Thanks
And 6 months later I was googling a problem in StackOverflow to which I gave a useful comment. Its like getting help from yourself in the past:)
In general:
Application.DecimalSeparator
would save you, if you are concatenating a string formula in non-English Excel VBA.
Selection.Formula would return the formula in English:
=VLOOKUP("Something",[VIT.xlsx]Monatsbericht!C2:C5,2,0)
Selection.FormulaLocal would return the formula in the local Excel language (German in this case):
=SVERWEIS("Something";[VIT.xlsx]Monatsbericht!C2:C5;2;0)
Selection.FormulaR1C1 would return the formula in R1C1 format, in English:
=VLOOKUP("Something",[UHL.xlsx]Monatsbericht!R[-15]C[-1]:R[-12]C[-1],2,0)
Selection.FormulaR1C1Local would return the formula in R1C1 format, in the local language:
=SVERWEIS("Something";[UHL.xlsx]Monatsbericht!Z(-15)S(-1):Z(-12)S(-1);2;0)

Is there a way to programmatically insert formulas into a csv file using vb.net?

I need to add formulas to a CSV file that already exists. Is this possible to do this using VB.Net?
The idea is I already have a CSV file and I need one column to be populated in each cell with a custom formula. This has to be done programmatically because these files are being created dynamically.
Does anyone know how to do this? Thanks.
1,2,3,=SUM(A1:C1)
Surprised me when I tried it, but Excel will keep the formula.
You can even export formulas into a CSV by first displaying them on screen.
(Ctrl-`)
While I stand by that my original answer is technically correct, I have been getting a lot of downvotes on this. Apparently popular spreadsheet software such as Microsoft Excel, Open Office, Libre Office Calc will calculate formulas that are entered into a CSV file. However, I would still not recommend relying in this capability.
Original answer:
The CSV format does not support formulas. It is a plain text only format.
You can import formula's into excel via a text file using comma separated values. Just remember to make sure it is named with the suffix .txt.
Then do the import.
My example import ( Data table, From Text)
Column1,Column2,ResultColumn
1,2,=A2+B2
It imported and computed just fine
Are you generating the CSV file? If so, consider writing an actual Excel file. (I'm assuming you're importing into Excel, since you used the term "cell", which has no meaning in CSV.)
Here's a link on how to do it: Create Excel (.XLS and .XLSX) file from C#
If you aren't generating the CSV, and if all you want is to add a new, calculated value,(rather than a formula that will change dynamically as cells change values) you can do this easily enough by reading in the CSV file, parsing each line enough to get the values you need for your formula, calculating the result, and appending it (after a comma) to each line before writing the line out to a new file.
You could open the csv in Excel and then add the formulas to Excel and save back out to csv. You would do this by using the Microsoft Excel 11.0 Object Library. Then
dim wb as Excel.Workbook
dim exApp as New Excel.Application
dim exSheet as Excel.Worksheet
dim rowNum as integer = 1
wb = System.Runtime.InteropServices.Marshal.BindToMoniker(pathAndFileNameOfCSV)
exApp = wb.Parent
exApp.DisplayAlerts = False
exApp.AlertBeforeOverwriting = False
exSheet = exApp.ActiveWorkbook.Sheets.Item(1)
'do your functions in a loop here i.e.
exSheet.Range("A" & rowNum).Value = "=SUM($A$1:$D$4)"
rowNum += 1
wb.Close (True) 'closes and saves
Saving the workbook should convert the formulas back to the values when it is closed.
In Excel, to import formulas with commas the formula must be encapsulated by double quotes to prevent the formula being spread across cells. For example:
2,4,6,13,=sum(A1:C1),"=if(A1=C1,D1-A1,D1+A1)"
Another quirk of Excel is that if you have a string consisting entirely of numbers, you must present it as a formula to retain leading zeros. "00012345" imports as 12345, ignoring the quotes. To import as text, the .CSV file must present this as ="00012345".

Calling Worksheet functions from vba in foreign language versions of Excel

The following code snipet run OK in an English Language verion of Excel, however when attempting to run this code in the same workbook in a Portuguese version of Excel it errors out.
' Add color bars on every other row - attempt to make list
' easier to read.
' "PlaceAt" is a worksheet range passed into the function
With Range(PlaceAt.offset(1, 0), PlaceAt.offset(i + 1, 7))
.FormatConditions.Add Type:=xlExpression, Formula1:="=MOD(ROW(),2)=1"
.FormatConditions(1).Interior.ColorIndex = 20
End With
I believe that the problem is, in Portuguese, the ROW function is spelled LIN (not sure what the MOD function would be) and that since the function is inserted using vba, Excel's translation function does not have the opportunity to translate the function names as it normally would when opening the document.
Any ideas?
Yes FormatConditions formulas must use the local format.
My workaround is to write the wanted formula into a cell an then get the FormulaLocal of this cell which should be the exact translation in your language:
Dim tmpCell As Range
Set tmpCell = Range("IV1")
tmpCell.Formula = "=mod(row(),2)=0"
.FormatConditions.Add(xlExpression, Formula1:=tmpCell.FormulaLocal)
Don't know if there is a cleaner solution, but if so I'd like to know, so please share...
I found a cleaner solution in a different question:
Names.Add "translate", RefersTo:="=MOD(ROW(),2)=1" ' Generic separator (,) and function name (ROW).
.FormatConditions.Add Type:=xlExpression, Formula1:=Names("translate").RefersToLocal ' Local separator (;) and function name (LIN).
Names("translate").Delete
Excel 2019 - 365 version still has this issue present. I found it occurring when using the VBA in conjunction with MS Excel Named Range Manager.
Example of error I am facing, which I fixed modifying Pragmateek's 2013 answer.
In the Named Range Manager exists a named range that uses the OFFSET function.
When calling this named range and using it in VBA to set another range variable USING the Application.Intersect method results in object errors because in VBA the MS Excel named range is acquired as a string. The intersect method then attempts to determine the intersect of this string and another range. This of course fails due to OFFSET working in English MS Excel versions, however not in Portuguese / Spanish .... And I imagine other languages.
Fixing this involved:
' Names!XXXXX = "=OFFSET('DummySheet'!$AO$7,0,0,1,'DummySheet'!$AM$2)""
Sub evaluate()
...
xAxis = Names!XXXXXX
Dim tempvar As Range: Set tempvar = Range("C1")
tempvar.Formula = xAxis ' set the range to hold the formula
tempvar.Formula = tempvar.FormulaLocal ' set the range to hold the formula in the local language
Set rng = Application.Intersect(tempvar.EntireColumn, yAxis.RefersToRange.EntireRow)
This worked well. However if ANYONE has a cleaner solution, please post suggestions. Cheers!

Copy excel rows in visual basic .net (VS 2008, .NET FrameWork 3.5)

SOLUTION FOUND: CHECK BOTTOM OF POST
Hello,
I'm using the excel object model (importing namespace Microsoft.Office.Interop.Excel) to open an Excel.Application object in my code, then open a workbook, worksheet, etc. What I'm doing is ridiculously simple: I'm opening two worksheet objects; one is already populated with data and another one is empty and is supposed to be populated with some rows from the first worksheet. If some conditions, regarding cells in the first worksheet, are not met, then I want to copy the entire row in the second worksheet, at the first available row. I have an integer counter, initialized at 1, which indexes the first empty row in the output worksheet this counter is obviously incremented every time I insert a row at outputSheet.Rows(counter).
Every solution I've Googled either uses VBA (I'm looking for a solution based on VB.NET) or is not compatible with .NET framework 3.5 (I'm receiving exceptions at runtime). I'm guessing I'm not using the Range object correctly or something; in any case, what's the simplest way to do this? I really don't want to open an OLEDB connection to my excel file: this is too complicated for the simple row copying mechanism I'm trying to implement.
Thanks,
Jason
Edit #1: Typical kind of excel records I Have to deal with:
1 | V | 1 | 01078215 | 02 | full name
2| V | 1 | 8048321 | 01| full name
If, for example, the fourth cell of a row is not 8 digits long, I want to copy the row AS IS to a second excel file.
Edit#2: Code:
'copy a row from an excel spreadsheet to another
Sub CopyRowTo(ByVal input As Excel.Worksheet,
ByVal output As Excel.Worksheet,
ByVal row_in As Integer,
ByVal row_out As Integer)
input.Activate()
input.Rows(row_in).Select()
input.Rows(row_in).Copy()
output.Activate()
output.Rows(row_out).Select()
output.Rows(row_out).Paste()
End Sub
Called As : CopyRowTo(inputSheet, outputSheet, 1, 1)
#
SOLUTION FOUND:
I have found the solution to my problem. The following code did the trick:
input.Activate()
input.Rows(row_in).Copy()
output.Activate()
output.Rows(row_out).Select()
output.Paste()
It appears that, for some reason, I need to apply the paste method to the Excel.Worksheet object, after having Select() - ed the range contained within that object (I do not get VB.NET at all, honestly).
Thanks,
J
#
If you're within the limitations of the free version (150 rows per sheet, up to 5 worksheets), the Gembox library makes it easy:
http://www.gemboxsoftware.com/GBSpreadsheetFree.htm
There are probably other similar things available.