Can we use Cell Range Validation to populate a dropdown list in excel from another sheet in EPPLUS - excel

I am new to using EPplus. I actually wanted to populate a dropdown list in Sheet1 from a list of values in Sheet2. This can be achieved by Cell Range Validation in Excel.But I am not sure whether EPPlus support this programmatically. It will be really helpful if anyone could help me out.
Populate a dropdown in this Designation Column from Designation Column in Sheet 2.
Sheet 2

Here's how to do it:
var departmentSheet = excel.Workbook.Worksheets.Add("department");
departmentSheet.Cells["A1"].Value = "Management";
departmentSheet.Cells["A2"].Value = "Administrator";
departmentSheet.Cells["A3"].Value = "Quality Engineering";
departmentSheet.Cells["A4"].Value = "Enablers";
var designationSheet = excel.Workbook.Worksheets.Add("designations");
designationSheet.Cells["A1"].Value = "Developer 1";
designationSheet.Cells["A2"].Value = "Developer 2";
designationSheet.Cells["A3"].Value = "Developer 3";
designationSheet.Cells["A4"].Value = "Developer 4";
// add a validation and set values
// the range of cells that will contain the validation
var validation = departmentSheet.DataValidations.AddListValidation("B1:B4");
// set validation rules as required
validation.ShowErrorMessage = true;
validation.ErrorStyle = ExcelDataValidationWarningStyle.warning;
validation.ErrorTitle = "An invalid value was entered";
validation.Error = "Select a value from the list";
// set the range that contains the validation list
validation.Formula.ExcelFormula = $"={ designationSheet.Name }!$A$1:$A$4";

Related

match single cell value with column of values for every match return those rows Google-apps-script

I have a spreadsheet with 2 tabbed sheets. I am trying to run a macro so that when the user inputs a name in B2 of the 2nd sheet, it is matched with every instance of that name in the 1st sheet, column B. I then need to copy all of the data that appears in the matched cell's rows and have that pasted in the 2nd sheet starting with cell B3.
I have limited experience with VBA, but none with JS/Google-apps-script. Any help with how to write this would be greatly appreciated! Here is my first shot:
function onSearch() {
// raw data sheet
var original = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Responses 2");
// search for student sheet
var filtered = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Student Progress Search");
// retrieving the values in the raw data array of names
var searchColumn = 2;
var lr = original.getLastRow();
var searchRange = original.getRange(2,searchColumn, lr, 1).getValues();
// retrieving the name submitted on search
var inputName = filtered.getRange(2, 2).getValue();
// loop through all the names in the raw data and identify any matches to the search name
for (var i = 0; i < lr; i++){
var dataValue = searchRange[i];
var r = dataValue.getRow();
var line = [[r]];
var paste = filtered.getRange(3, 3);
// if the data is a match, return the value of that cell in the searched sheet
if (dataValue == inputName){ return paste.setValues(line);
}
}
}
Not sure if the built-in QUERY function would work for you. This here does exactly what you are looking for:
=QUERY(Sheet1!B:B,"select B where LOWER(B) like LOWER('%" &B2& "%')")
For example, if a user enters 'joe', the function will match any entry containing 'joe', regardless of case.

How can I shift the "subitems" in an Excel PivotTable to another column?

I generate an Excel sheet which contains data formatted like so:
IOW, the "Total Packages", "Total Purchases", "Average Price", and "% of Total" values are located in a column of their own (Data) for each overarching (or sidearching) description.
When I PivotTablize this data, it places these values beneath each description:
This makes sense, but those accustomed to the previous appearance want it to be replicated in the PivotTable. How can I shift the Description "subitems" in the PivotTable to their own column?
This is the code I use to generate the PivotTable:
private void PopulatePivotTableSheet()
{
string NORTHWEST_CORNER_OF_PIVOT_TABLE = "A6";
AddPrePivotTableDataToPivotTableSheet();
var dataRange = rawDataWorksheet.Cells[rawDataWorksheet.Dimension.Address];
dataRange.AutoFitColumns();
var pivotTable = pivotTableWorksheet.PivotTables.Add(
pivotTableWorksheet.Cells[NORTHWEST_CORNER_OF_PIVOT_TABLE],
dataRange,
"PivotTable");
pivotTable.MultipleFieldFilters = true;
pivotTable.GridDropZones = false;
pivotTable.Outline = false;
pivotTable.OutlineData = false;
pivotTable.ShowError = true;
pivotTable.ErrorCaption = "[error]";
pivotTable.ShowHeaders = true;
pivotTable.UseAutoFormatting = true;
pivotTable.ApplyWidthHeightFormats = true;
pivotTable.ShowDrill = true;
// Row field[s]
var descRowField = pivotTable.Fields["Description"];
pivotTable.RowFields.Add(descRowField);
// Column field[s]
var monthYrColField = pivotTable.Fields["MonthYr"];
pivotTable.ColumnFields.Add(monthYrColField);
// Data field[s]
var totQtyField = pivotTable.Fields["TotalQty"];
pivotTable.DataFields.Add(totQtyField);
var totPriceField = pivotTable.Fields["TotalPrice"];
pivotTable.DataFields.Add(totPriceField);
// Don't know how to calc these vals here, so have to grab them from the source data sheet
var avgPriceField = pivotTable.Fields["AvgPrice"];
pivotTable.DataFields.Add(avgPriceField);
var prcntgOfTotalField = pivotTable.Fields["PrcntgOfTotal"];
pivotTable.DataFields.Add(prcntgOfTotalField);
}
So there is one RowField ("MonthYr") with values such as "201509" and "201510", one ColumnField ("Description") and four DataFields, which align themseles under the Description column field. I want to shift those four fields to the right, to their own column, and the Description label to be vertically centered between those four values to their left. [How] is this possible?
Try changing the layout of your table with
pivotTable.RowAxisLayout xlTabularRow
pivotTable.MergeLabels = True
this is the result:
A little script in C# with Interop.Excel. Included the using ;)
using Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
var excelApp = new Excel.Application();
Excel.Workbook wb = excelApp.Workbooks.Open(#"e:\42\TestSO.xlsx");
Worksheet ws = wb.Worksheets["SheetName"];
PivotTable pt = ws.PivotTables("DynamicTableName");
pt.RowAxisLayout(XlLayoutRowType.xlTabularRow);
pt.MergeLabels = true;
wb.Save();
wb.Close();
Marshal.ReleaseComObject(ws);
It's all about PivotTable layout / design... here's the manual way - Salvador has the VBA way :)...

How can I create a PivotTable using EPPlus to filter on the rows in one column and also a set of columns?

To create a PivotTable, source data needs to be provided from which to generate the PivotTable.
I have generated a "dummy" sheet for this purpose which contains raw data such as:
I need to generate a Pivot Table from that data so that it is generated like so:
IOW, it needs to have a filter on the "Description" column that allows the rows to be filtered (only show "Peppers" or whatever) AND a filter on which month columns to display (the sheet can have up to 13 month columns (Sep 15, Oct 15, etc.)) so that the user can choose 1..13 of those "month year" columns to display (technically, they could choose 0, but what would be the point)?
How can this be done? I've tried the following:
private void AddPivotTable()
{
var dataRange
rawDataWorksheet.Cells[rawDataWorksheet.Dimension.Address];
dataRange.AutoFitColumns();
var pivotTable
usagePivotWorksheet.PivotTables.Add(usagePivotWorksheet.Cells["A6"]
dataRange, "ProdUsagePivot");
pivotTable.MultipleFieldFilters = true;
pivotTable.GridDropZones = false;
pivotTable.Outline = false;
pivotTable.OutlineData = false;
pivotTable.ShowError = true;
pivotTable.ErrorCaption = "[error]";
pivotTable.ShowHeaders = true;
pivotTable.UseAutoFormatting = true;
pivotTable.ApplyWidthHeightFormats = true;
pivotTable.ShowDrill = true;
var descPageField = pivotTable.Fields["Description"];
pivotTable.PageFields.Add(descPageField);
descPageField.Sort
OfficeOpenXml.Table.PivotTable.eSortType.Ascending;
var descRowField = pivotTable.Fields["Description"];
pivotTable.RowFields.Add(descRowField);
. . . add others later
}
...but only get the filter for "Description" with no data beneath it:
What do I need to do yet to get the desired appearance/functionality?
Try this:
Create the entire PivotTable as usual and after adding all the required fields and calculations, move the DataPivotFields as RowFields.
In VBA will be something like this:
With PivotTable
.DataPivotField.Orientation = xlRowField
.Position = 2
End With
Also need to apply this: PivotTable.MergeLabels = True to have the Description cell merged for all the corresponding totals.
PD. Replace PivotTable with the PivotTable object in your code

Find value on any sheet in spreadsheets using Google Script

Using the code below I'm able to look through multiple sheets in a spreadsheet to find the first value that equals the selected cell. The only problem with this bit is: The cell with the value found is highlighted yellow, but the cell with the value found isn't selected. See code below for hopping through sheets. I can't get my head around this :)
Funny thing is that the code for highlighting and selecting a value does work when I'm not hopping through the list of sheets, see the best answer: Find value in spreadsheet using google script
function SearchAndFind() {
//determine value of selected cell
var sh = SpreadsheetApp.getActiveSpreadsheet();
var ss = sh.getActiveSheet();
var cell = ss.getActiveCell();
var value = cell.getValue();
//create array with sheets in active spreadsheet
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
//loop through sheets to look for value
for (var i in sheets) {
//Set active cell to A1 on each sheet to start looking from there
SpreadsheetApp.setActiveSheet(sheets[i])
var sheet = sh.getActiveSheet();
var range = sheet.getRange("A1");
sheet.setActiveRange(range);
//set variables to loop through data on each sheet
var activeR = cell.getRow()-1;
var activeC = cell.getColumn()-1;
var data = sheets[i].getDataRange().getValues()
var step = 0
//loop through data on the sheet
for(var r=activeR;r<data.length;++r){
for(var c=activeC;c<data[0].length;++c){
step++
Logger.log(step+' -- '+value+' = '+data[r][c]);
if(data[r][c]==''||step==1){ continue };
if(value.toString().toLowerCase()==data[r][c].toString().toLowerCase()){
sheet.getRange(r+1,c+1).activate().setBackground('#ffff55');
return;
}
}
}
}
}
This code is able to search across multiple sheets, it is obviously based on your published code but uses a memory (scriptProperties) to keep the search value 'alive' when changing from one sheet to the next one and to know when to search for it.
It has 2 non-optimal aspects : 1° you have to keep searching up to the last occurrence before you can begin a new search.
2° : when it switches from sheet n to sheet n+1 it first selects cell A1 before finding the value occurrence.
I guess it should be possible to get rid of these issues but right now I don't find how :-)
Maybe the approach is simply not the best, I started from a simple one sheet script modified and complexified... that's usually not the best development strategy (I know), but anyway, it was a funny experiment and a good logic exercise ...
Thanks for that.
function SearchAndFind() {
//determine value of selected cell
var sh = SpreadsheetApp.getActiveSpreadsheet();
var ss = sh.getActiveSheet();
var cell = ss.getActiveCell();
var value = cell.getValue();
if(ScriptProperties.getProperty('valueToFind')!=''){value = ScriptProperties.getProperty('valueToFind')};
//create array with sheets in active spreadsheet
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets()
var sheetNumber = sheets.length;
var currentSheet = ss.getIndex()-1;
Logger.log(currentSheet);
//loop through sheets to look for value
for (var i = currentSheet ; i<sheetNumber ; ++i ){
Logger.log('currentSheet = '+i)
//Set active cell to A1 on each sheet to start looking from there
SpreadsheetApp.setActiveSheet(sheets[i])
// sheets[i].getRange(1,1).activate();
//set variables to loop through data on each sheet
var activeR = cell.getRow()-1;
var activeC = cell.getColumn()-1;
var data = sheets[i].getDataRange().getValues()
var step = 0;
//loop through data on sheet
for(var r=activeR;r<data.length;++r){
for(var c=activeC;c<data[0].length;++c){
step++
Logger.log('sheet : '+i+' step:'+step+' value '+value+' = '+data[r][c]);
if(data[r][c]==''||(step==1&&i==currentSheet)){ continue };
if(value.toString().toLowerCase()==data[r][c].toString().toLowerCase()){
sheets[i].getRange(r+1,c+1).activate().setBackground('#ffff55');
ScriptProperties.setProperty('valueToFind',value);
return;
}
}
}
cell = sheets[i].getRange(1,1);
}
ScriptProperties.setProperty('valueToFind','');
Logger.log('reset');
}

How to get the value in an Excel dropdown using C#

I am looking for code to open and read an Excel file, any version of Excel, including 2010. One of my columns has a dropdown in it. I need to get the value of the selected item in the dropdown. I would eventually want to populate these values into a business object.
If anyone has some code to share please let me know.
I am using C# and Visual Studio 2010.
Thanks.
I know the VBA for both the ActiveX combo and the forms dropdown, and based on that, I can give you some very inexpert notes for c# for the forms dropdown, the combo eludes me as yet.
Working with notes from: http://support.microsoft.com/kb/302084
//Get a new workbook.
oWB = (Excel._Workbook)(oXL.Workbooks.Open("C:\\Docs\\Book1.xls"));
//3rd Sheet
oSheet = (Excel._Worksheet)oWB.Sheets.get_Item(3);
//This will return an index number
var i = oSheet.Shapes.Item("Drop Down 1").ControlFormat.Value;
//This will return the fill range
var r = oSheet.Shapes.Item("Drop Down 1").ControlFormat.ListFillRange;
oRng = oSheet.get_Range(r);
//This will return the value of the dropdown, based on the index
//and fillrange
var a =oRng.get_Item(i).Value;
//Just to check
textBox1.Text = a;
This may help with an ActiveX combo, but I have only half got it to work:
using MSForm = Microsoft.Vbe.Interop.Forms;
<...>
Excel.OLEObject cbOLEObj = (Excel.OLEObject)workSheet.OLEObjects("ComboBox1");
MSForm.ComboBox ComboBox1 = (MsForm.ComboBox) cbOLEObj.Object;
Console.WriteLine(ComboBox1.Text);
From: http://www.eggheadcafe.com/community/aspnet/66/10117559/excel-get-value-from-a-combobox.aspx

Resources