I am creating a excel Add-in using visual studio 2010. I was able to get the cell address using this code.
label1.Label = Globals.MyAddIn.Application.ActiveCell.Address.ToString();
I want to get the cell value. Also if you can tell me how to set a value for a given cell.
Please help.
to get a cell value for the active cell the following should do it
var cellValue = Globals.MyAddIn.Application.ActiveCell.Value.ToString()
or for a specific cell
var cellValue = Globals.MyAddIn.Application.Cells("A1").Value.ToString()
To Set the value it is basically the reverse
Globals.MyAddIn.Application.Cells("A1").Value = "ABC123"
EDIT
Try this. I know that this works as I have something like it working in my own addin.
int row = 1;
int col = 1;
var sheet1 = (Excel.Worksheet)Application.ActiveWorkbook.Worksheets["Sheet1"];
sheet1.Cells[row, col] = "ABC123";
string cellValue = sheet1.Cells[row,col];
Related
I've been getting problems trying to reference a dynamic range in google sheets to apply my function to: essentially replacing special characters and empty cells within a given data range with 0s, works perfectly if I gave it a static range but cant seem to do a dynamic one. Thanks alot for any help offered
Code thus far:
function replaceValues() {
var sheet1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
var lastRow = sheet1.getDataRange().getLastRow()
var firstRow = sheet1.getDataRange().getRow("B2")
var targetValue1 = '-'
var targetValue2 = ''
var targetValue3 = '$'
var subValue = 0
for(var i =0; i=targetValue1; i++); {
var valueRng = sheet1.getRange(firstRow,lastRow);
var newValues = valueRng.getValues()[i].setValues(subValue);
}
}
Select the range before going the the menu and executing the function or build a modeless dialog and you can make the selection and capture on the custom dialog with a button click.
Demo:
If you have a range, you can do search and replace inside it this way:
range.createTextFinder('aaa').replaceAllWith('b');
Or with RegExp:
range.createTextFinder('a+').useRegularExpression(true).replaceAllWith('b');
I still don't understand what exactly you're trying to gain. So here is a guess how your script might look like:
function replaceValues() {
var sheet1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
var range = sheet1.getDataRange(); // is the range dynamic enough?
// replace '$' and '-' with '0'
range.createTextFinder("[\$-]").useRegularExpression(true).replaceAllWith('0');
// replace '' with '0'
var data = range.getValues();
data.forEach((row,r) => row.forEach((cell,c) =>
data[r][c] = data[r][c].toString().replace(/^$/,'0')));
range.setValues(data);
}
I have 5 possible locations where a user can enter either: "Yes, No, or any URL". If a URL is entered, I need the value of that cell (the URL) to be entered into an equation on a corresponding cell in a separate sheet. Here is what I have:
//Locations of the cells where the user can enter the URL.
var graphic1_loc = 'A62';
var graphic2_loc = 'A63';
var graphic3_loc = 'A64';
var graphic4_loc = 'A65';
var graphic5_loc = 'A66';
//The corresponding locations on the "Briefing" sheet where the images would get inserted.
var graphic1_placement = 'B45';
var graphic2_placement = 'B46';
var graphic3_placement = 'B47';
var graphic4_placement = 'B48';
var graphic5_placement = 'B49';
//main_gen is the name of the sheet where the user enters the data. This just grabs the value
//the user entered and stores it in the corresponding variable.
var graphic1 = SpreadsheetApp.getActiveSheet().getRange('main_gen!'+graphic1_loc).getValue();
var graphic2 = SpreadsheetApp.getActiveSheet().getRange('main_gen!'+graphic2_loc).getValue();
var graphic3 = SpreadsheetApp.getActiveSheet().getRange('main_gen!'+graphic3_loc).getValue();
var graphic4 = SpreadsheetApp.getActiveSheet().getRange('main_gen!'+graphic4_loc).getValue();
var graphic5 = SpreadsheetApp.getActiveSheet().getRange('main_gen!'+graphic5_loc).getValue();
var graphics_placements = ["B45", "B46", "B47", "B48", "B49"]; //These are the corresponding cells where the image would be placed on a separate sheet.
//If any graphic is a URL, insert that image into it's corresponding cell in the Briefing tab.
for (var num = 0; num < 5; num ++) {
var graphicformula = '=IMAGE("' + graphic[num] + '",1)';
if (graphic[num].length > 5) {
SpreadsheetApp.getActiveSheet().getRange('Briefing!'+graphic[num]_placement).setFormula(graphicformula);
}
}
What I am trying to get the If statement within the For Loop to say is...If the length of the value of graphic1 is > 5 (if it isn't yes (3) or no (2) then it is assumed it is a URL) then find the corresponding cell on the "Briefing" sheet to insert the formula. The current way I have it written is not correct, but I wanted to attempt to write something to give you an idea of what I am after. Thanks for any help you can provide!
You want to run SpreadsheetApp.getActiveSheet().getRange('Briefing!'+graphic[num]_placement).setFormula(graphicformula); when the value of graphic# is URL.
For example, when the URL is in the cell A63 in the sheet main_gen, you want to put the formula of =IMAGE(URL,1) to the cell B46 in the sheet Briefing
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
Modification points:
In your script, you are trying to use graphic[num] as a variable of graphic1, graphic2,,,. In this case, this cannot be used as the variable.
In your situation, the cells A62:A66 in the sheet main_gen are correspoinding to the cells B45:B49 in the sheet Briefing. I think that this can be used for modifying your script.
The values of the cells A62:A66 in the sheet main_gen can be retrieved by ss.getSheetByName("main_gen").getRange("A62:A66").getValues().
In order to confirm whether the value of cell is the URL, in this modification, I used test().
I think that when the destination sheet is declared out of the for loop, the process cost can be reduced.
When above points are reflected to your script, it becomes as follows.
Modified script:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getSheetByName("main_gen").getRange("A62:A66").getValues();
var dstSheet = ss.getSheetByName("Briefing");
var graphics_placements = ["B45", "B46", "B47", "B48", "B49"];
for (var num = 0; num < source.length; num ++) {
if (/https?:\/\//.test(source[num][0])) {
var graphicformula = '=IMAGE("' + source[num][0] + '",1)';
dstSheet.getRange(graphics_placements[num]).setFormula(graphicformula);
}
}
References:
test()
getValues()
If I misunderstood your question and this was not the direction you want, I apologize.
I am trying to create a dependent list as described and answered (with a script) here.
I would like to achieve that if selecting a certain value (e.g. "First") from a cell in column 1, then the drop-down options from the next cell in the same row should offer a range of values from the column in a different sheet with the same heading as the value in the first - left - cell (i.e. the first sheet is called "Selector" - in which there are dropdowns, in the second sheet called "KAT" I have the options for these dropdowns). This should then be possible for every row depending on the value of each first cell of the row.
I have tried to use and adapt the suggested script and have reviewed the sample files in the article but I apparently lack some basic understanding of the script to be able to adapt and implement it properly.
Could anybody kindly help me with making this dynamic dropdown work properly?
Just to clarify my final intention: I would like to have this script working first to be able to use it on multiple files. My final goal, though, is to make self-filling dropdown lists and selectors, so that I could simply fill in the data in the "Selector" sheet and would then be able to select these same values later in the cells below (depending on the name (value) of the first cell in the row = first cell of the column holding validation range). I hope to be able to achieve this by using either Pivot table or any other formula in the "KAT" sheet that would aggregate my data from "Selector" sheet and feed them back as drop-down options ...).
Thank you for your help.
See the example sheet here
Code I used (as above):
function onEdit()
{
var ss = SpreadsheetApp.getActiveSpreadsheet(),
sheet = ss.getActiveSheet(),
name = sheet.getName();
if (name != 'Selector') return;
var range = sheet.getActiveRange(),
col = range.getColumn();
if (col != 1) return;
var val = range.getValue(),
dv = ss.getSheetByName('KAT'),
data = dv.getDataRange().getValues(),
catCol = data[0].indexOf(val),
list = [];
Logger.log(catCol)
for (var i = 1, len = 100; i < len; i++) // Problem is here, you have too many items in list! Cannot have more 500 items for validation
list.push(data[i][catCol]);
var listRange = dv.getRange(2,catCol +1,dv.getLastRow() - 1, 1)
Logger.log(list)
var cell = sheet.getRange(range.getRow(), col-1)
var rule = SpreadsheetApp.newDataValidation()
.requireValueInRange(listRange) // Use requireValueIn Range instead to fix the problem
.build();
cell.setDataValidation(rule);
Logger.log(cell.getRow())
}
This question deals with dynamic dropdown lists. A previous question and answer on StackOverflow (Google Sheets - Dependent drop-down lists) were referenced, and code from that answer was being unsuccessfully re-purposed.
The code in the question was not working for one reason: Line 20
var cell = sheet.getRange(range.getRow(), col-1)
In the referenced code, the dropdown list begins in Column F (col=6). The dependant dropdowns ranged to the left so the definition of the dependant column was "col-1". In the questioner's scenario, the dropdown list begins in Column A (col=1) and the dependant dropdowns range from left to right. However, this line of code was not changed to take into account the different layout. Rather than "col-1", it should be "col+1".
Other matters
In addition to this, lines 16 and 17 perform a loop to create an array that might be used for the dependant dropdown. However the loop is redundant because the dropdown is actual defined by creating and assigning a range on the "KAT" sheet.
Cell A2 of KAT includes a formula:
=sort(unique(Selector!$A$2:$A),1,true)
This may appear to be useful because it automatically adds any new dropdown value entered in "Selector" to a list of values in KAT. In reality it is unproductive, because the dependant dropdown build by the code works vertically rather than horizontally. So an additional row added to KAT does not, of itself, contribute to building the dependant dropdown.
The following code works to build the dependant drop down list. I have deliberately left a number of "Logger" entries in the code to assist the questioner in understanding how the code works.
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var name = sheet.getName();
if (name != 'Selector') return;
var range = sheet.getActiveRange();
var col = range.getColumn();
var dropdownrow = range.getRow(); // added for debugging and informationm
if (col != 1) return;
var val = range.getValue();
Logger.log("the cursor is in 'Selector' in cell = " + range.getA1Notation()); //DEBUG
Logger.log("That's row " + dropdownrow + ", and column " + col + ". The value selected = " + val); // DEBUG
var dv = ss.getSheetByName('KAT');
var data = dv.getDataRange().getValues();
var catCol = data[0].indexOf(val);
var list = [];
var KAT_data = dv.getDataRange();
var KAT_data_len = KAT_data.getLastRow(); // added to give 'for' loop a sensible range
Logger.log("The data range on KAT is " + KAT_data.getA1Notation() + ", and the last row of data = " + KAT_data_len); //DEBUG
Logger.log("KAT data = '" + data + "'"); // DEBUG
Logger.log("Found the dropdown cell value of '" + val + "' in KAT as item #" + catCol); //DEBUG
for (var i = 1, len = KAT_data_len; i < len; i++) { // Irrelevant because the data validation range is obtained by defining a range on KAT
// Problem is here, the unique command in A2 creates a blank row
// Logger.log("i="+i+", data = "+data[i][catCol]); // DEBUG
list.push(data[i][catCol]);
}
var listRange = dv.getRange(2, catCol + 1, dv.getLastRow() - 1, 1);
Logger.log("FWIW, this is the list after the loop= " + list); // DEBUG
Logger.log("The contents for the new data validation range (taken from KAT) is " + listRange.getA1Notation()); // DEBUG
Logger.log("The new validation range gets added to col = " + (col + 1)); // DEBUG
//var cell = sheet.getRange(range.getRow(), col-1); // governs the next validation range. Example validation worked right to left, but this sheet works left to right. So must ADD 1, not subtract 1.
var cell = sheet.getRange(range.getRow(), col + 1);
Logger.log("The cell to be assigned the new validation range will be " + cell.getA1Notation()); // DEBUG
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(listRange).build(); // Build validation rule
cell.setDataValidation(rule); // assign validation range to new cell
}
Is this code worthwhile?
The code, as written and referenced, is limited to creating only one level of dependant dropdowns. To this extent it has very limited value. A different approach to creating dependant dropdowns is justified.
"How do you do dynamic / dependent drop downs in Google Sheets?" on StackOverflow has been a meeting place for discussing and updating techniques for dynamic dependant dropdowns since 2014. The latest update was in February 2018 by Max Makhrov. Thye code described here may be useful for the questioner.
I'm trying to create a drop down menu with contents based on a another cell in the same row. For example if A1 = 'yes' then the drop down in B2 gives you the options of 'yes' or 'no'. I can do this I have the list data set up and to code works. The problem is I need to do this 155 times in 4 different sheets. Is there a faster way to do this than right clicking and editing the data validation rules for each cell. Here's a link to the test sheet I'm working on :
https://docs.google.com/spreadsheets/d/1rd_Ig_wpof9R_L0IiA1aZ9syO7BWxb6jvBhPqG8Jmm4/edit?usp=sharing
You can set data validation rules with a script, as documented here. Here's a reference for starting with Apps scripts.
I wrote a function that does approximately what you described. It works with the range B3:B157 of the sheet '9th grade' in the current spreadsheet. For each of them, it sets the validation rule to be: a value in the same row, columns B and C of sheet 'List Data'. The line with
....... = listData.getRange(i+3, 2, 1, 2);
will need to be modified if the source range of validation is to be different. Here, the parameters are: starting row, starting column, number of rows, number of columns. So, 2 columns starting with the second, in row numbered i+3.
function setRules() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var grade = ss.getSheetByName('9th Grade');
var listData = ss.getSheetByName('List Data');
var range = grade.getRange('B3:B157');
var rules = range.getDataValidations();
for (var i = 0; i < rules.length; i++) {
var sourceRange = listData.getRange(i+3, 2, 1, 2);
rules[i][0] = SpreadsheetApp.newDataValidation().requireValueInRange(sourceRange).build();
}
range.setDataValidations(rules);
}
I land in this issue for a diferent reason: "Just mass DataValidation copy (or update) in one column". Thanks, to user3717023 that bring me a light.
I hope that helps someone this simplification.
function setRules() {
//select spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var leads = ss.getSheetByName('Leads');
//Select correct Datavalidation
var rangeNewDataValidation = leads.getRange('M2:M2');
var rule = rangeNewDataValidation.getDataValidations();
//Copy (or Update) Datavalidation in a specific (13 or 'M') column
var newRule = rule[0][0].copy();
Logger.log(leads.getMaxRows())
for( var i=3; i <= leads.getMaxRows(); i++){
var range = leads.getRange(i, 13);
range.setDataValidations([[newRule.build()]]);
}
}
Here is what I am trying to do. I have a list that populates a drop down list created by data validation. I then query the data to populate a second list based on the first drop down value. Everything works except I would like to set the first value in the second drop down to be the default value. In other words if I change the value in the first drop down my second drop down now shows an error until I select the drop down and change the value to a correct value. I would like to set it to the first correct value when the first drop down is changed. My reason for this is I dont want someone to forget to change the second drop down and get a value that is not even in the range.
Please help I am new to this kind of thing.
thanks
https://docs.google.com/spreadsheets/d/1U2_0Ku1bCLfDh_v2XyE9aQMSfdYmlVfX_8SKmQay48g/edit?usp=sharing
Here is what I have so far. It works except anytime the sheet is edited the value is reset. I only want it to reset when Cell A2 changes.
function onEdit() {
var ss = SpreadsheetApp.getActive()
var sheet = SpreadsheetApp.getActiveSheet();
// IF(cellContent has changed) then clear B2
// else do nothing.
sheet.getRange('B2').clearContent();
var value = sheet.getRange('H2').getValue();
sheet.getRange('B2').setValue(value);
}
I figured it out and this seems to work just fine.
function onEdit() {
var sheet = SpreadsheetApp.getActiveSheet();
var cell = sheet.getActiveCell();
var cellR = cell.getRow();
var cellC = cell.getColumn();
var cellValue = cell.getValue();
var active_spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var value = active_spreadsheet.getRange('H2').getValue();
if (cellR == 2 && cellC == 1) {
sheet.getRange('B2').clearContent();
sheet.getRange('B2').setValue(value);
}
}