Related
I have a program that generates some raw data. I have a sheet 'A' which has the raw data columns that I've referenced to create charts and tables on 'Summary' sheet.
Now I have re-run the program that generates the raw data and put it in sheet 'B'.
How can I change the reference of sheet 'A' in the 'Summary' sheet to 'B'?
I tried renaming sheet 'A' to 'old_A' and renaming 'B' to 'A' but that didn't work because google automatically changed all the references on 'Summary' to 'old_A'.
assuming you were referring to two tabs A & B within a sheet.
take a copy of the sheet
rename the raw tab in this copy_sheet to B
now you have all the formulas in summary pointing to B
copy this whole of summary tab and paste it directly onto Original Summary tab. since the design/structure is same, the copy-paste shouldn't be of an hindrance.
The following illustration should help:
Here is what I found for Google Sheets:
To get the current sheet name in Google sheets, the following simple script can help you without entering the name manually, please do as this:
Click Tools > Script editor
In the opened project window, copy and paste the below script code into the blank Code window, see screenshot:
......................
function sheetName() {
return SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
}
Then save the code window, and go back to the sheet that you want to get its name, then enter this formula: =sheetName() in a cell, and press Enter key, the sheet name will be displayed at once.
See this link with added screenshots: https://www.extendoffice.com/documents/excel/5222-google-sheets-get-list-of-sheets.html
You have 2 options, and I am not sure if I am a fan of either of them, but that is my opinion. You may feel differently:
Option 1: Force the function to run.
A function in a cell does not run unless it references a cell that has changed. Changing a sheet name does not trigger any functions in the spreadsheet. But we can force the function to run by passing a range to it and whenever an item in that range changes, the function will trigger.
You can use the below script to create a custom function which will retrieve the name:
function mySheetName() {
var key = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
return key;
}
and in the cell place the following:
=mySheetName(A1:Z)
Now if any value in a cell in that passed range changes the script will run. This takes a second to run the script and sets a message in the cell each time any value is changed so this could become annoying very quickly. As already mentioned, it also requires a change in the range to cause it to trigger, so not really helpful on a fairly static file.
Option 2: Use the OnChange Event
While the run time feels better than the above option, and this does not depend on a value changing in the spreadsheet's cells, I do not like this because it forces where the name goes. You could use a Utilities sheet to define this location in various sheets if you wish. Below is the basic idea and may get you started if you like this option.
The OnChange event is triggered when the sheet name is changed. You can make the code below more sophisticated to check for errors, check the sheet ID to only work on a given sheet, etc. The basic code, however, is:
function setSheetName(e) {
var key = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('K1').setValue(key);
}
Once you have saved the code, in the script editor set the Current Project's On Change Trigger to this function. It will write the sheet name to cell K1 on any change event. To set the trigger, select Current project's triggers under the Edit menu.
If you reference the sheet from another sheet, you can get the sheet name using the CELL function. You can then use regex to extract out the sheet name.
=REGEXREPLACE(CELL("address",'SHEET NAME'!A1),"'?([^']+)'?!.*","$1")
update:
The formula will automatically update 'SHEET NAME' with future changes, but you will need to reference a cell (such as A1) on that sheet when the formula is originally entered.
Not using script:
I think I've found a stupid workaround using =cell() and a helper sheet. Thus avoiding custom functions and apps script.
=cell("address",[reference]) will provide you with a string reference (i.e. "$A$1") to the address of the cell referred to. Problem is it will not provide the sheet reference unless the cell is in a different sheet!
So:
where
This also works for named sheets. Then by all means adjust to work for your use case.
Source: https://docs.google.com/spreadsheets/d/1_iTD6if3Br6nV5Bn5vd0E0xRCKcXhJLZOQqkuSWvDtE/edit#gid=1898848593
EDIT:
I've added another workaround in the document that makes use of =formulatext() and some traditional text functions. By referencing to a cell in the current sheet using it's full address, i.e. Sheet1A1 you are able to use formulatext() to extract only the sheet name.
Here is my proposal for a script which returns the name of the sheet from its position in the sheet list in parameter. If no parameter is provided, the current sheet name is returned.
function sheetName(idx) {
if (!idx)
return SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
else {
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
var idx = parseInt(idx);
if (isNaN(idx) || idx < 1 || sheets.length < idx)
throw "Invalid parameter (it should be a number from 0 to "+sheets.length+")";
return sheets[idx-1].getName();
}
}
You can then use it in a cell like any function
=sheetName() // display current sheet name
=sheetName(1) // display first sheet name
=sheetName(5) // display 5th sheet name
As described by other answers, you need to add this code in a script with :
Tools > Script editor
An old thread, but a useful one... so here's some additional code.
First, in response to Craig's point about the regex being overly greedy and failing for sheet names containing a single quote, this should do the trick (replace 'SHEETNAME'!A1 with your own sheet & cell reference):
=IF(TODAY()=TODAY(), SUBSTITUTE(REGEXREPLACE(CELL("address",'SHEETNAME'!A1),"'?(.+?)'?!\$.*","$1"),"''","'", ""), "")
It uses a lazy match (the ".+?") to find a character string (squotes included) that may or may not be enclosed by squotes but is definitely terminated by bang dollar ("!$") followed by any number of characters. Google Sheets actually protects squotes within a sheet name by appending another squote (as in ''), so the SUBSTITUTE is needed to reduce these back to single squotes.
The formula also allows for sheet names that contain bangs ("!"), but will fail for names using bang dollars ("!$") - if you really need to make your sheet names to look like full absolute cell references then put a separating character between the bang and the dollar (such as a space).
Note that it will only work correctly when pointed at a different sheet from the one that the formula resides! This is because CELL("address" returns just the cell reference (not the sheet name) when used on the same sheet. If you need a sheet to show its own name then put the formula in a cell on another sheet, point it at your target sheet, and then reference the formula cell from the target sheet. I often have a "Meta" sheet in my workbooks to hold settings, common values, database matching criteria, etc so that's also where I put this formula.
As others have said many times above, Google Sheets will only notice changes to the sheet name if you set the workbook's recalculation to "On change and every minute" which you can find on the File|Settings|Calculation menu. It can take up to a whole minute for the change to be picked up.
Secondly, if like me you happen to need an inter-operable formula that works on both Google Sheets and Excel (which for older versions at least doesn't have the REGEXREPLACE function), try:
=IF(IFERROR(INFO("release"), 0)=0, IF(TODAY()=TODAY(), SUBSTITUTE(REGEXREPLACE(CELL("address",'SHEETNAME'!A1),"'?(.+?)'?!\$.*","$1"),"''","'", ""), ""), MID(CELL("filename",'SHEETNAME'!A1),FIND("]",CELL("filename",'SHEETNAME'!A1))+1,255))
This uses INFO("release") to determine which platform we are on... Excel returns a number >0 whereas Google Sheets does not implement the INFO function and generates an error which the formula traps into a 0 and uses for numerical comparison. The Google code branch is as above.
For clarity and completeness, this is the Excel-only version (which does correctly return the name of the sheet it resides on):
=MID(CELL("filename",'SHEETNAME'!A1),FIND("]",CELL("filename",'SHEETNAME'!A1))+1,255)
It looks for the "]" filename terminator in the output of CELL("filename" and extracts the sheet name from the remaining part of the string using the MID function. Excel doesn't allow sheet names to contain "]" so this works for all possible sheet names. In the inter-operable version, Excel is happy to be fed a call to the non-existent REGEXREPLACE function because it never gets to execute the Google code branch.
I have a sheet that is made to used by others and I have quite a few indirect() references around, so I need to formulaically handle a changed sheet tab name.
I used the formula from JohnP2 (below) but was having trouble because it didn't update automatically when a sheet name was changed. You need to go to the actual formula, make an arbitrary change and refresh to run it again.
=REGEXREPLACE(CELL("address",'SHEET NAME'!A1),"'?([^']+)'?!.*","$1")
I solved this by using info found in this solution on how to force a function to refresh. It may not be the most elegant solution, but it forced Sheets to pay attention to this cell and update it regularly, so that it catches an updated sheet title.
=IF(TODAY()=TODAY(), REGEXREPLACE(CELL("address",'SHEET NAME'!A1),"'?([^']+)'?!.*","$1"), "")
Using this, Sheets know to refresh this cell every time you make a change, which results in the address being updated whenever it gets renamed by a user.
I got this to finally work in a semi-automatic fashion without the use of scripts... but it does take up 3 cells to pull it off. Borrowing from a bit from previous answers, I start with a cell that has nothing more than =NOW() it in to show the time. For example, we'll put this into cell A1...
=NOW()
This function updates automatically every minute. In the next cell, put a pointer formula using the sheets own name to point to the previous cell. For example, we'll put this in A2...
='Sheet Name'!A1
Cell formatting aside, cell A1 and A2 should at this point display the same content... namely the current time.
And, the last cell is the part I'm borrowing from previous solutions using a regex expression to pull the fomula from the second cell and then strip out the name of the sheet from said formula. For example, we'll put this into cell A3...
=REGEXREPLACE(FORMULATEXT(A2),"='?([^']+)'?!.*","$1")
At this point, the resultant value displayed in A3 should be the name of the sheet.
From my experience, as soon as the name of the sheet is changed, the formula in A2 is immediately updated. However that's not enough to trigger A3 to update. But, every minute when cell A1 recalculates the time, the result of the formula in cell A2 is subsequently updated and then that in turn triggers A3 to update with the new sheet name. It's not a compact solution... but it does seem to work.
To match rare sheets names like:
Wow!
Oh'Really!
''!
use the formula:
=SUBSTITUTE(REGEXEXTRACT(CELL("address";Sheet500!A1);"'?((?U).*)'?!\$[A-Za-z]+\$\d+$");"''";"'")
or
=IF(NOW();SUBSTITUTE(REGEXEXTRACT(FORMULATEXT(A1);"='?((?U).*)'?![A-Za-z]+\d+$");"''";"'")) if A1 is formula reference to your sheet.
if you want to use build-in functions:
=REGEXEXTRACT(cell("address";'Sheet1'!A1);"^'(.*)'!\$A\$1$")
Explanation:
cell("address";'Sheet1'!A1) gives you the address of the sheet, output is 'Sheet1'!$A$1. Now we need to extract the actual sheet name from this output. I'm using REGEXEXTRACT to match it by regex ^'(.*)'!\$A\$1$, but you can either use more/less specific regex or use functions like SUBSTITUTE or REPLACE
I have a google sheet where the cells in the first tab pull data from cells on the second tab.
for example Sheet1 cell A1 has =Sheet2!A1
This is true for every cell on Sheet1
When I do a File - Download As - Microsoft Excel (.xlsx)
It exports the cells with formulas. Is there a way to export the sheets as values and not formulas
In this case, Sheet1 cell A1 would not contain =Sheet2!A1 but the value of =Sheet2!A1?
You can copy your original google spreadsheet and, in the copy, change the formula for the first cell for each tab to import data from the original one:
=IMPORTRANGE("spreadsheet id","'tab name'!range")
Ex:
=IMPORTRANGE("1C-PS4wAHS8ssCNgVDfOsssREAz7PjuQGX23Rk0sssss","'measurement with spaces'!A12:F44")
The ID you can get via original spreadsheet URL:
https://docs.google.com/spreadsheets/d/1C-PS4wAHS8ssCNgVDfOsssREAz7PjuQGX23Rk0sssss/edit#gid=99999999
The exported xlsx file from the copy will have only the values
#fabceolins answer is simple and good for normal scenarios, i noticed however Excel will still contain reference to IMPORTRANGE formula which can cause access issues.
I created Google App script to copy in the following method.
If you can use Google App scripts, add the following functions:
function update_view(dup_id, TL="A1", BR="Z991") {
// Open current Sheet
var ss = SpreadsheetApp.getActiveSpreadsheet()
// Supply a duplicate google doc ID. This document will be exported to excel
var ds = SpreadsheetApp.openById(dup_id)
// UI element for notifying in the google sheets
var ui = SpreadsheetApp.getUi()
//Copy each sheet one by one
var sheets = ss.getSheets();
for (i=0; i<sheets.length; i++) {
src_sheet = sheets[i];
sheet_name = src_sheet.getName();
// If same sheet exists in the destination delete it and create an empty one
dst_sheet = ds.getSheetByName(sheet_name);
if (dst_sheet != null) {
ds.deleteSheet(dst_sheet)
}
dst_sheet = ds.insertSheet(sheet_name);
//set column width correctly
for(j=1; j<=src_sheet.getLastColumn(); j++){
dst_sheet.setColumnWidth(j, src_sheet.getColumnWidth(j))
}
src_range = src_sheet.getRange(TL + ":" + BR);
dst_range = dst_sheet.getRange(TL + ":" + BR);
//Note: DisplayValues is set as Values, formulas are removed in dup sheet
dst_range.setValues(src_range.getDisplayValues());
//Nice to haves for formatting
dst_range.setFontColors(src_range.getFontColors());
dst_range.setFontStyles(src_range.getFontStyles());
dst_range.setBackgrounds(src_range.getBackgrounds());
dst_range.setHorizontalAlignments(src_range.getHorizontalAlignments());
dst_range.setVerticalAlignments(src_range.getVerticalAlignments());
dst_range.setWraps(src_range.getWraps());
dst_contents_range = dst_sheet.getDataRange();
dst_contents_range.setBorder(true, true, true, true, true, true);
}
//Completed copy, Now open the dup document and export.
ui.alert("Backup Complete, Please open " + dup_id + " sheet to view contents.")
}
function update_mydoc_view(){
// https://docs.google.com/spreadsheets/d/<spreadsheet_id>/
update_view("<spreadsheet_id>")
}
To run the function, go to tools->macros->import , import the function and run update_mydoc_view().
After it is completed, export the google sheet into an excel document.
If you want to download a single sheet spreadsheet, instead of download it as .XLSX, download it as .CSV.
If by open the .CSV file by double clicking it shows strange characters, the default encoding of your computer is different from the one used by the Google servers, to fix this do the following:
Open Excel
Click File > Open
Select the .CSV file
The import wizard will be shown. One of the steps will allow you to select the file encoding, select UTF-8.
Once you finish with the import wizard save your file as .XLSX
Related
Microsoft Excel mangles Diacritics in .csv files?
Is it possible to force Excel recognize UTF-8 CSV files automatically?
I did the following and it worked for me :
Duplicate the file
CTRL+A > CTRL+X > CTRL + V Paste Value only (from the paste icon displayed after pressing CTRL+V)
If you want to keep only the values from Sheet1, just select the data in the sheet, copy it, open a new Excel work book and when you paste, rather than using the conventional hotkeys Ctrl+V, right click cell A1 and select Paste values under the Paste options category of the right click menu.
If the problem is that the downloaded Excel does not have functional formulas that take information from your second sheet and instead show the formulas as text, do what the previous commenter said. check your view to make sure you are not in formula view. use the hotkey Ctrl+ ~, or go to the view tab to check your view options.
By default this is what happens - you will see the values not the formula.
Are you sure you are not in formula view in Excel?
If you check "Show formula" it will switch in formula view.
Or generally speaking you can try those:
MS Excel showing the formula in a cell instead of the resulting value
I would be surprised if it was indeed a google sheet problem - it's about Excel display.
When I import a csv file to Google spreadsheet a single quote get added in front of all numeric data.
How can I remove that ?
I using import option from file menu
Try this:
right-click the column letter (on columns with numbers)
press Ctrl+F to invoke Google Sheets Search
to the right of the search box, click the ⋮ vertical 3 dots button
to invoke the Find and replace window
in the Find box, put the ' single quote (no space after)
leave the Replace box empty
click the Replace all button (on the bottom)
That should do the trick
put a column in notepad ++ enter image description here
make replace, and return column to GD
For me "Find and Replace" didn't work since those single quotes are not found by it.
I could only get rid of the single quotes by formatting affected cells/column as an integer numeric one.
I would like to open a specific sheet of a Google Sheets from a hyperlink in another spreadsheet.
I have different links in my master spreadsheet and each should have a hyperlink to the same slave spreadsheet but to a different sheet.
I know hyperlink function but it doesn't go to a specific sheet.
You can use this custom script (Tools > Script Editor) function and connect it with e.g. custom drawing (Insert > Drawing... > Save and Close, then right click on new drawing> Assign Script... > "goToSheet2")
function goToSheet2() {
goToSheet("Sheet2");
}
function goToSheet(sheetName) {
var sheet = SpreadsheetApp.getActive().getSheetByName(sheetName);
SpreadsheetApp.setActiveSheet(sheet);
}
Update:
In the newest version you can select cell and add link (Insert > Link) and select link to specific sheet directly:
The HYPERLINK function can link to another sheet in the same workbook; if you observe the URL of the spreadsheet, at the end of it there is #gid=x where x is unique for each sheet.
The problem is, it will open the sheet as a new instance of the spreadsheet in another tab, which is probably not desirable. The workaround would be to insert images or drawings as buttons, and assigning a script to them that will activate specific sheets.
I personnaly did this based on what #rejthy said:
In scripts I created this function:
/**
* Return the id of the sheet. (by name)
*
* #return The ID of the sheet
* #customfunction
*/
function GET_SHEET_ID(sheetName) {
var sheetId = SpreadsheetApp.getActive().getSheetByName(sheetName).getSheetId();
return sheetId;
}
and then in my sheet where I need the link I did this: =HYPERLINK("#gid="&GET_SHEET_ID("Factures - "&$B$1);"Année en cours")
So what I understand from the OP is that you have one master spreadsheet that you want to have links to individual sheets, where one or more of those sheets may be in single or multiple spreadsheet files.
The HYPERLINK function only turns a URL into a hyperlink and is really only useful when you want to have hypertext instead of just a link. If you enter the raw URL as the data, it's automatically turned into a hyperlink, so there's no additional work.
As mentioned in other answers, the solution is to have the spreadsheet's URL then use the gid value to calculate the link to the desired sheet within the spreadsheet. You can write a simple app that collects all of the individual sheets' links and writes them into the master.
Below are some snippets of pseudocode (Python) that can help you get started. I'm leaving out all the boilerplate auth code, but if you need it, see this blog post and this video. The code below assumes your API service endpoint is SHEETS.
This reads a target spreadsheet to build links for each of its sheets:
# open target Sheet, get all sheets & Sheet URL
SHEET_ID = TARGET_SHEET_DRIVE_FILE_ID
res = SHEETS.spreadsheets().get(spreadsheetId=SHEET_ID,
fields='sheets,spreadsheetUrl').execute()
sheets = res.get('sheets', [])
url = res['spreadsheetUrl']
# for each sheet, dump out its name & full URL
for sheet in sheets:
data = sheet['properties']
print('** Sheet title: %r' % data['title'])
print(' - Link: %s#gid=%s' % (url, data['sheetId']))
Instead of printing to the screen, let's say you stored them in a (name, URL) 2-tuple array in your app, so bottom-line, it looks something like this list called sheet_data:
sheet_data = [
('Intro', 'https://docs.google.com/spreadsheets/d/SHEET_ID/edit#gid=5'),
('XData', 'https://docs.google.com/spreadsheets/d/SHEET_ID/edit#gid=3'),
('YData', 'https://docs.google.com/spreadsheets/d/SHEET_ID/edit#gid=7')
]
You can then write them to the master (starting from the upper-left corner, cell A1) like this:
SHEET_ID = MASTER_SHEET_DRIVE_FILE_ID
SHEETS.spreadsheets().values().update(
spreadsheetId=SHEET_ID, range='A1',
body={'values': sheet_data},
valueInputOption='USER_ENTERED'
).execute()
Some caveats when using gid:
The first default sheet created for you (Sheet1) always has a gid=0.
Any sheets you add after that will have a random gid.
Don't bank on a gid=0 for the 1st sheet in your spreadsheets however as you or someone else may have deleted the original default sheet, like my example above.
If you want to see more examples of using the Sheets API, here are more videos I've made (along with posts that delve into each code sample):
Migrating SQL data to a Sheet plus code deep dive post
Formatting text using the Sheets API plus code deep dive post
Generating slides from spreadsheet data plus code deep dive post
Then when you open up the master in the Sheets UI, you can clickthrough to any of the individual sheets, regardless of which spreadsheet files they're in. If you want them automatically opened by another app or script, most programming languages offer developers a ways to launch a web browser given the target URL. In Python, it would be the webbrowser module (docs):
import webbrowser
webbrowser.open_new(url) # or webbrowser.open_new_tab(url)
Alternatively, you can try creating a custom function. With the spreadsheet open, click the Tools menu, then Script editor.... Paste the code into the editor:
/**
* Gets the Sheet ID from Sheet Name
*
* #param {string} input The Sheet Name
* #return The Sheet ID
* #customfunction
*/
function SHEETID(input) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var tab = ss.getSheetByName(input);
return tab.getSheetId();
}
Save, refresh the spreadsheet, and then type in your custom function
=SHEETID("Your Custom Sheet Name")
=SHEETID(A1)
And voila! The unique ID for the tab (in the current spreadsheet) is output. You can hyperlink to it by using the following formula:
=HYPERLINK("#gid="&SHEETID(A1),"Link")
In case you want to create a link to another sheet which will open the sheet in the same browser tab here is what you want to do:
1. Get the id of the sheet. Check the link in your browser and you will see #gid=x where x is the sheet id
2. Then you want to set the formula (hyperlink) to the cell and make it show as a hyperlink
SpreadsheetApp.getActiveSheet().getRange("A1").setFormula('=HYPERLINK("#gid=X","test")').setShowHyperlink(true);
If you don't use setShowHyperlink(true) it will be shown as a regular text.
This is basically a code version for the update provided by #rejthy above