Skip to main content

Writing a Simple QR Code Stock Control Spreadsheet

At Theatre, Film & TV they have lots of equipment they loan to students, cameras, microphone, tripod etc. Keeping track of what goes out and what comes back is a difficult job. I have seen a few other departments struggling with the similar "equipment inventory" problems.

A solution I have prototyped uses QR codes, a Google Spreadsheet and a small web application written in Apps Script. The idea is, that each piece of equipment ( or maybe collection of items ) has a QR code on it. Using a standard and free smartphone application to read QR codes, the technician swipes the item and is shown a screen that lets them either check the item out or return it.

The QR app looks like this.



The spreadsheet contains a list of cameras. It has links to images and uses Google Visualisation tools to generate its QR codes. The spreadsheet looks like this.


The Web Application

The web application, which only checks items in or out and should be used on a phone in conjunction with a QR code scanner iphone app, like Scan.
The application is written in Apps Script looks like this below. It shows the current status of that particular camera and lets you check a camera out.


Building This Application

There's a strange "chicken and egg" situation about building this application. In order to create a QR code that would lead to an individual camera, you first need to "Publish" your web app so that we have the URL to your application. Once published we can use the URL for our application and start populating the spreadsheet with cameras.

Populating the spreadsheet

First, I added some URLs to pictures of cameras, and titles and descriptions to my spreadsheet.
Next, in the spreadsheet in cell C2 you can see the formula...

=CONCAT("https://script.google.com/a/macros/york.ac.uk/s/YOUR_URL_GOES_HERE/exec?id=",A2)

… this formula creates the URL that is appended with "?id=231" etc and will be used to generate a unique QR code image.
In cell D2 I have the formula …

=make_QR(C2)

… this formula calls an Apps Script function that looks like this...

function make_QR( url ) {
  /*
  Note: If you add a number to the domain, as per the documentation, the https starts erroring. I think.
  Note: URLs are limited to 2K in length 
  From: https://google-developers.appspot.com/chart/infographics/docs/overview
  */
  
  var size = 150 // The height and width needed.
  var encoded_url = encodeURIComponent( url )  
  var image_url = "http://chart.googleapis.com/chart?chs=" + size + "x" + size + "&cht=qr&chl=" + encoded_url
  return image_url
}

… this takes our unique URLs and uses Google Visualisation Tools to create an image for the QR code, one of which looks like this.

We can display the image in the spreadsheet using the formula...

=Image(D2,1)

Deprecation Warning!

Although the Charting service is being deprecated, it's probably good to use until April 2015. See https://developers.google.com/chart/terms. I imagine it would be easy to generate and download all the QR code images you need, finding an alternative QR creation API in a few years time.

Creating The Web Application

The first part of the application gets the data from our spreadsheet, finding the relevant row. It then builds an application using UiApp objects for the values we want to display.
function doGet(e) { 
  if (typeof e.parameter.id  == 'undefined'){
    return no_id(e) // The URL doesn't have an ?id=345 on the end! 
  }
  
  var id  = parseInt( e.parameter.id ) // This is the id of the row in the spreadsheet.
  
  // Get the data from the spreadsheet and get the row that matches the id
  var this_spreadsheet_id = ScriptProperties.getProperty('this_spreadsheet_id')
  var ss = SpreadsheetApp.openById(this_spreadsheet_id)
  var sheet = ss.getSheetByName("Sheet1")
  var range = sheet.getDataRange()
  var last_row = range.getLastRow()
  var last_column = range.getLastColumn()
  
  for(i = 2; i <= last_row ; i++){
    var this_row = sheet.getRange(i,1 , 1, last_column)
    var values = this_row.getValues()[0]
    var row_id = parseInt( values[0] )
    if ( row_id == id){
      var title = values[5]
      var details = values[8]
      var status_txt = values[7]  
      Logger.log( "STATUS: " + status )
      var image_url = values[4]
      }
  }
  
  // Create an application
  var app = UiApp.createApplication().setTitle("Check in/out").setHeight(250).setWidth(400)
  
  // Create the layout
  var grid = app.createGrid(8, 3 ).setStyleAttribute(3, 1, "width", "420px").setCellPadding(5).setBorderWidth(0).setId('grid')
  grid.setStyleAttribute("margin-left", "auto").setStyleAttribute("margin-right", "auto")
  grid.setStyleAttribute("margin-top", "100px")
  
  
  var image = app.createImage(image_url).setWidth(100).setHeight(100).setStyleAttribute("margin-left", "auto").setStyleAttribute("margin-right", "auto")
  grid.setWidget(0, 1, image)
  ... and so on...  and so on ... 


We then need to create the buttons, like so...

  // Check in button
  var handler = app.createServerHandler('check_in').addCallbackElement(grid)
  var check_in_button = app.createButton('Check in', handler).setStyleAttribute("font-size", "24px")
  check_in_button.setId("check_in_button")
  grid.setWidget(4, 1, check_in_button)


… Later in the code we create a function ( or handler ) for the button. It updates our spreadsheet with CHECKED IN or CHECKED OUT, and also updates a few interface elements like this....
function check_out(e){
  var id = parseInt(e.parameter.id)
  Logger.log( "id: " + id )
  
  try{
    // Update the QR spreadsheet
    var this_spreadsheet_id = ScriptProperties.getProperty('this_spreadsheet_id')
    var ss = SpreadsheetApp.openById(this_spreadsheet_id)
    var sheet = ss.getSheetByName("Sheet1")
    var range = sheet.getDataRange()
    var last_row = range.getLastRow()
    var last_column = range.getLastColumn()
    
    for(i = 2; i <= last_row ; i++){
      var this_row = sheet.getRange(i, 1 , 1, last_column)
      var values = this_row.getValues()[0]
      var row_id = parseInt( values[0] )
      
      if ( row_id == id){
        var title = values[5]
        //var status_txt = values[7]
        var range = sheet.getRange(i, 8)
        range.setValue("CHECKED OUT")
        Logger.log( "Spreadsheet: CHECKED OUT")
        break
      }
    }
    
    var app = UiApp.getActiveApplication()
    
    //Update infoBox
    var infoBox = app.getElementById("infoBox")
    infoBox.setVisible( true ).setText( title + " has been checked out")
    
    var status = app.getElementById("status")
    var status_css = {'background': 'red', 'color': 'white'}
    status.setText("CHECKED OUT").setStyleAttributes(status_css)
    
    var grid = app.getElementById("grid")
    
    grid.setStyleAttribute(3, 1, 'background', 'red')
    
    grid.setStyleAttribute(5, 1, 'visibility', 'hidden')
    grid.setStyleAttribute(4, 1, 'visibility', 'inherit')
    
    
  }catch(e){
    Logger.log(e)
  }
  
  return app
  
}


… I used CSS to show and hide the non-relevant button. It's a bit clunky, but it does the trick ( please make better code available if you know how, .setVisible(false) didn't seem to work ).

And To Finish...

I added a listing application, if somebody might accidentally view the app without using one of the unique URLs in the spreadsheet. It looks like this. It displays all the cameras and might need some pagination if there were too many to display easily.



Generating a Google Document To Print Off the QR Codes

It was easy to take the QR codes and make a Google Document to easily format and print off onto labels. Like this...
function make_a_document(){
  var this_spreadsheet_id = ScriptProperties.getProperty('this_spreadsheet_id')
    var ss = SpreadsheetApp.openById(this_spreadsheet_id)
    var sheet = ss.getSheetByName("Sheet1")
    var range = sheet.getDataRange()
    var last_row = range.getLastRow()
    var last_column = range.getLastColumn()
    
    var doc = DocumentApp.create("QR Example Printable Document")
    var body = doc.getBody()
    //var table = body.appendTable()
    
    for(i = 2; i <= last_row ; i++){
      var this_row = sheet.getRange(i,1 , 1, last_column)
      var values = this_row.getValues()[0]
      
      var id = parseInt( values[0] )
      var title = values[5]
      var image_url = values[4]
      var qr_code = values[3]
      
      // Get the images of the cameras and the QR codes
      var response = UrlFetchApp.fetch(qr_code)
      var image_blob = response.getBlob()
      
       var response = UrlFetchApp.fetch(image_url)
      var qr_blob = response.getBlob()
      
      var paragraph = body.appendParagraph('')
      var text = paragraph.appendText(id)
      text.setFontSize(24)
      
      var image_paragraph = paragraph.appendInlineImage(image_blob)
      image_paragraph.setHeight(150).setWidth( 150 )
      
      var qr_paragraph = paragraph.appendInlineImage(qr_blob)
      qr_paragraph.setHeight(150).setWidth( 150 )
      
      var paragraph = body.appendParagraph(title)
      paragraph.setFontSize(12)
      
      body.appendHorizontalRule()
      
      
      }
 }


… The Google document with QR codes in looks like this.


… and the application on my iPhone looks like this...




Comments

  1. Hi brother Tom Smith,
    You really a great inventor!
    I went thru your page bout how you did this inventory control apps using google & some other tools. Thank you for sharing.
    Actually i linked to here from google search engine when i was looking for a solution for my caretaking school's student attendance system which they wanted to be paperless.
    I planned to suggest a solution that, a teacher should scan student's unique QRcode in their ID tag and this will update the student's attendance record in google spreadsheet.
    I know its easy for a person like u but im blurred as i dont have experience in scripting.
    I really hope & appreciate if you could give your hands as my Mentor. And of course I'll credit & highlight you in my credit to the management.
    Please contact me thru any following medium:
    Gmail: ekshiva@gmail.com
    Google+ : Shivaneshwaran Jayabalan
    FB : Shivaneshwaran Jayabalan (KLshiva)

    Thank you in advance.
    Shiva
    IT Administrator

    ReplyDelete
    Replies
    1. Hi bros Tom & Shiva.
      I'm on the same path of Shiva trying to scan qr codes to track attendance (students signing in and out several times on the same day). I figured students could substitute equipment and use a similar system, but i need help too. Thank you very much for any light, Carlos@c2labs.cc

      Delete
  2. Hi Tom,

    I'm really interested in getting this up and running in our organisation. Every time I scan a QR code that's been generated, I get the following error:

    ReferenceError: "no_id" is not defined.

    The debug identifies this line as the problem:

    if (typeof e.parameter.id == 'undefined'){

    Any idea what the issue could be?

    Thanks,

    Dave

    ReplyDelete
  3. Ah... I've missed out a page of code... the no_id function is in here...

    https://docs.google.com/a/york.ac.uk/spreadsheet/ccc?key=0Ajnu7JgRtB5CdG43YVJiZmxfcWh3NEthYVpjVG1mY0E&usp=drive_web#gid=0

    You can either make a copy of this spreadsheet and re-make the web app or copy-and-paste the no_id function into your code. ( pasted below ).


    function no_id(e){
    // Someone has browsed an empty URL, tsk, tsk! Get all the items ( needs limiting really ).

    var this_spreadsheet_id = ScriptProperties.getProperty('this_spreadsheet_id')
    var ss = SpreadsheetApp.openById(this_spreadsheet_id)
    var sheet = ss.getSheetByName("Sheet1")
    var range = sheet.getDataRange()
    var last_row = range.getLastRow()
    Logger.log( last_row + " rows" )
    var last_column = range.getLastColumn()

    var app = UiApp.createApplication().setTitle("Check in/out").setHeight(250).setWidth(400)

    // Create the layout
    var grid = app.createGrid(last_row+2, 3 ).setStyleAttribute(3, 1, "width", "420px").setCellPadding(5).setBorderWidth(0).setId('grid')
    grid.setStyleAttribute("margin-left", "auto").setStyleAttribute("margin-right", "auto")
    grid.setStyleAttribute("margin-top", "100px")

    //var banner = app.createInlineLabel().setText("QR Example App").setStyleAttribute("font-size", "24px")
    //grid.setWidget(0, 1, banner)


    for(i = 2; i <= last_row ; i++){
    var this_row = sheet.getRange(i,1 , 1, last_column)
    var values = this_row.getValues()[0]
    var row_id = parseInt( values[0] )
    var title = values[5]
    var status_txt = values[7]
    var image_url = values[4]
    var url = ScriptApp.getService().getUrl( ) + "?id=" + row_id

    var grid_num = i-1

    var image = app.createImage(image_url).setWidth(100).setHeight(100)
    image.setStyleAttribute("margin-left", "auto").setStyleAttribute("margin-right", "auto")
    image.setId("image_" + grid_num)
    grid.setWidget(grid_num, 0, image)

    var text_label = app.createInlineLabel().setText(title).setStyleAttribute("font-size", "18px")
    text_label.setId("text_" + grid_num)
    grid.setWidget(grid_num, 1, text_label)

    var link = app.createAnchor(status_txt, url)
    link.setId("link_" + grid_num)
    grid.setWidget(grid_num, 2, link)

    Logger.log( "status_txt: " + status_txt + " " + typeof status_txt )
    if ( status_txt.toString() == 'CHECKED OUT'){
    grid.setStyleAttributes(grid_num, 2, {'background':'red','color':'white', 'font-size':'24px'})
    }else{
    grid.setStyleAttributes(grid_num, 2, {'background':'green','color':'white', 'font-size':'24px'})
    }
    }

    app.add(grid);

    return app
    }


    ReplyDelete
  4. But it sounds that the URLs ( to this app ) that are being generated don't have ?id=5 on the end...

    This is the chicken and egg problem I mentioned... you have to...

    a. Publish your app so you know the URL
    b. Generate a formula to create your links ( in column C )
    c. Generate your QR codes in column D ... which gives you the images needed
    d. Print off your codes
    e. Scan them with a smart phone QR reader...

    Hope that helps

    ReplyDelete
    Replies
    1. Thanks for the reply Tom. That error is gone but now I get:

      Invalid argument: Id

      My links definitely have the ID at the end:

      https://script.google.com/a/macros/wcppe.org.uk/s/AKfycbzvzF8-kyLk3KqSNojeGOuvUrH3PE0DvSL7Lb70BVCy35dkfvk/exec?id=213

      but still don't work.

      My spreadsheet is here: https://docs.google.com/spreadsheet/ccc?key=0AibRGVA7sgnsdENWTFlhMTZyRjVxUTVDZ1hUQnlFdEE&usp=sharing

      Can you spot anything obvious that I'm missing?

      Delete
  5. I can't... I've made a copy of your spreadsheet and looked at that, it looks good.

    Are you familiar with wrapping code with a try statement. Like this...

    try{
    main web app code here
    }catch(e){
    Logger.log( e + " " + e.lineNumber + " " + e.stack )
    }

    ... this may help you work out where the error is...

    ReplyDelete
  6. Found it!

    By wrapping the main web app code in...

    try{
    main_code_here
    }catch(e){
    var html = HtmlService.createHtmlOutput(e + "
    " + e.lineNumber + "
    " + e.stack)
    return html
    }

    ... I found out it was line 18 giving the problems.

    You haven't added a this_spreadsheet_id project property to that project ( in Script Editor > File > Project properties > Project

    Copy that from your spreadsheet URL (from the key= bit ) and call it this_spreadsheet_id and you should be good to go

    ReplyDelete
    Replies
    1. I'm having the same problem but don't understand your fix.

      When I go to Editor > File > Project properties, I see a panel with 4 tabs
      Info, Scopes, User properties and Script properties. So, I'm lost.

      Also, the "Copy that URL" I see my id number after the = bit, but I don't understand where I call it this_spreadsheet_id ? Again, Lost.

      I'm a total newbie to coding and could use a little more direction if you have the time to help out.

      Thanks in advance.

      Erik

      Delete
  7. That worked!

    Thanks for the assist, really appreciate it.

    ReplyDelete
  8. No problem, it was the fault of the idiot that wrote the code in the first place.

    Guess I should fix up the article too... sigh... not ... enough... time...

    ReplyDelete
  9. Tom, can you email me or can I Skype or call you? kevin.cosby0@gmail.com

    ReplyDelete
  10. Tom,

    I'm very new to this, last time I coded Javascript was in high school about 7 years ago. Would you mind emailing me? I have a few questions. mpuckett259@gmail.com

    ReplyDelete
  11. hey tom smith

    would you help me in making the application of qr code to manage inventory by providing the code..

    it would be very helpful if u provide the code..

    thanking u..

    ReplyDelete
  12. tulsi

    all the code is there. Copy & paste.

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
  13. Hello Tom,
    I have read your article with great interest and have tried to make it run from my own Google account.
    I do seem to be having some difficulties which is not unexpected as I am a complete novice in scripting. I have sussed out most and think that the final hurdle is in the URL's. For example in =CONCAT("https://script.google.com/a/macros/york.ac.uk/s/YOUR_URL_GOES_HERE/exec?id=",A2) it seems to be the script URL generated when I publish the script but it doesn't work for me ( I assume that "York.ac.uk" also has to go).
    I also have trouble getting the "make_a_document" function to Work. I get a "Bad Value" in line 25 which is var ss = SpreadsheetApp.openById(this_spreadsheet_id). I have tried adding this_spreadsheet_id project property to that project ( in Script Editor > File > Project properties > Project but Again am in doubt about the URL.
    Your help will be greatly appreciated


    ReplyDelete
  14. Thank you so much! This is an awesome script!

    ReplyDelete
  15. And I thought that inventory management software things like this were too complicated for the average bear :D

    ReplyDelete
  16. I used script in excel spreed sheet, what I was looking for on different blogs, Currently the formula is Great & working fine.thanks for share with us!
    Static Dashboard

    ReplyDelete
  17. Hello Tom,

    I dont understand where to put the code, in script editor and which URL to use where.. Can you please explain once how it works.

    ReplyDelete
  18. This looks promising! Thanks for doing all of this work. A teacher in my school was wanting to put an inventory system for math equipment. I'll be putting this information to work and see how it all turns out. I'll keep you posted if I run into any hiccups or "happy accidents". :)

    ReplyDelete
  19. This comment has been removed by the author.

    ReplyDelete
  20. Tom, why do I get

    TypeError: Cannot read property "parameter" from undefined.

    on line 3?

    ReplyDelete
  21. You need to get the web app, in a browser, via the Published URL... not just "run" the code... where e is undefined.

    ReplyDelete
  22. got it, running good now. Thanks!

    ReplyDelete
  23. Hi Tom, I found that the make_a_document function gets stuck when there's no image url in my database. Do you have any suggestions?

    ReplyDelete
  24. Yes, DEBUG IT! :-)

    You could always check for that and if not use a "default image url"...

    Tom

    ReplyDelete
  25. Thanks for sharing ideas with us. We have nice post about Procurement. We support both B2B, B2C clients from Sourcing, Logistics Management, Procurement, Inventory Management, Warehousing Management, Reverse Auction. – www.buynormial.com

    ReplyDelete
  26. Thank you very much for posting this! It was a great help.
    Is there any way to add the "name" of the person who "checked out" the camera? And that this name then appears in the spreadsheet?
    Any pointers would be greatly appreciated.

    Many thanks again, Randy

    ReplyDelete
    Replies
    1. Hi Randy! Did you ever have any success with adding the user name of the person who last "checked in" or "checked out" the items? I'm just trying this application out myself and that would be a great addition! Let me know, and thanks!

      Delete
  27. Randy. I think, if you save the app as executng on behalf of the user, rather than running as you the developer then I guess you can ...

    var email = Session.getActiveUser().getEmail()

    ... Not sure if it works if you are running on behalf of you... And that only works for Google Apps domains...

    Alternatively, you could maybe have a drop-down... or send the "checker outerers" individualised urls with their names in...

    ReplyDelete
    Replies
    1. What URL exactly is it that gets pasted into the script formula in cell C2? I have copied the url that it gives me when I published the web app, and I have even tried shortening that URL, but I keep getting a " Sorry, the file you have requested does not exist" page. I tried adding the properties through script editor for "this_spreadsheet_id" and in the value I put the url of the google docs spreadsheet, but I am not sure if that is right. The url for my spreadsheet does not have the "key=" part to it. It looks to be a different type of format altogether.

      Delete
  28. What URL exactly is it that gets pasted into the script formula in cell C2? I have copied the url that it gives me when I published the web app, and I have even tried shortening that URL, but I keep getting a " Sorry, the file you have requested does not exist" page. I tried adding the properties through script editor for "this_spreadsheet_id" and in the value I put the url of the google docs spreadsheet, but I am not sure if that is right.

    ReplyDelete
  29. That's the URL to YOUR APP ( I think ). Follow the instructions, it's a bit tricky.

    ReplyDelete
  30. Is it possible to add an "equipment history" in order to see:
    - check in/out dates
    - loan to

    ReplyDelete
  31. This comment has been removed by the author.

    ReplyDelete
  32. Hi Tom

    Thank you for posting this, it's really helpful, but I'm getting an error in "make_a_document" and "no_id" function because of this line: var ss = SpreadsheetApp.openById(this_spreadsheet_id). The error message is: "Bad value (line __, file "Code").
    I already added the property this_spreadsheet_id to the project in Script properties, but I don't think that's the problem anyway, I tried to put the Id directly without the variable this_spreadsheet_id and I keep getting the same error. Can you give me a tip to solve this problem?

    ReplyDelete
  33. Hi Tom,

    Is it possible to adapt the webapp and scripts to allow for input on each item when scanned? I would like to implement this sort of system at my work to track fertilizer and chemical use and "checked in" "checked out" isn't quite what we need. Would be looking for an input box with an option of incoming or outgoing.

    Thanks,

    ReplyDelete
  34. Tom, so I need some help. I have done my best to try and follow your directions, but I am not sure the post is current because of all the additions in the comments. Can you please help? I would be most grateful.

    Here is my spreadsheet: https://docs.google.com/spreadsheets/d/1ZEQBkns_30miBBrU7WCheGhvIw6Jl-PsvpH13YL_j-A/edit?usp=sharing

    Here is my code from the single appscripts: https://docs.google.com/document/d/1WmTaPRuPcqNiy4IePd-YiOKRJ2HrWMCCebzG8fVQOec/edit?usp=sharing

    Any thoughts on what I am missing here, extra things you left out, etc.?

    ReplyDelete
  35. See it running here
    https://script.google.com/a/macros/york.ac.uk/s/AKfycbx6qnCEowXxpyVEAu3hlB8fceI4PyqIUWeHvl7CPlgWydpydo4p/exec?id=238

    You'll need to change the app url etc.

    ReplyDelete
  36. This is great, thanks for sharing this wonderful idea. I made some slight modification to track the last change and who made it.
    The only concern I have is that we lend items in quite big (5-10) batch and it might be time consuming to scan all of them and to wait for the app to load. I changed the url so that it changes the state of the item as soon as it's loaded to save some seconds but I feel as it could be handled better. As we do not have that many items (maybe 40 or so) I don't feel the reason to move to a commercial app.

    You may be glad that your idea is supporting a local Red Cross chapter managing its equipment tracking :)

    ReplyDelete
    Replies
    1. Daniele, I see you have it working. I'm having problems with the parts of code that are now deprecated. Can you post a doc with your code. Maybe I can troubleshoot my problem that way.

      Delete
    2. Hi Daniele, I was wondering if you could post your modifications? I have a very similar need where I have to track who is signing items out and they are signing out multiple items at once (trip leaders signing out gear for all their participants). I am working to modify the code similarly to what you are describing, but I have hitting a wall. Any hints will be greatly appreciated.

      Thanks,
      Jut

      Delete
  37. Hello Tom,

    I stumbled on this blog and found that it was exactly what I needed. Problem is that I'm having some problems getting it to work correctly. I keep getting this "Invalid argument: id" error when I click on the link. Here is a copy of the script i wrote:

    https://docs.google.com/document/d/1JuTMUUruiInfNSauEc8gIqmiYyyQbfB-pTivqFucaCY/edit?usp=sharing

    Is there any chance you can help me out? Any help would be greatly appreciated. Thanks in advance your consideration.

    ReplyDelete
  38. Also, I get the status is not defined when I press check in...

    ReplyDelete
  39. Also, I get the status is not defined when I press check in...

    ReplyDelete
  40. Thanks for sharing this wonderful idea.I agree with you.
    qrmaker

    ReplyDelete
  41. Thank you for such a fantastic blog. Where else could anyone get that kind of info written in such a perfect way? I have a presentation that I am presently working on, and I have been on the lookout for such information.
    print management services

    ReplyDelete
  42. Hi
    Dear what about if i need to create QR for cell A1 and B1, A2 and B2 … like:
    Name: ABDC
    Age: 28
    Address: gghatabb
    Tel: 1234567

    And i need to keep some ref. no beside the QR code

    Any help plz.

    Thank you.

    ReplyDelete
  43. Hello Everybody,
    My name is Mrs Anita. I live in UK London and i am a happy woman today? and i told my self that any lender that rescue my family from our poor situation, i will refer any person that is looking for loan to him, he gave me happiness to me and my family, i was in need of a loan of $250,000.00 to start my life all over as i am a single mother with 3 kids I met this honest and GOD fearing man loan lender that help me with a loan of $250,000.00 U.S. Dollar, he is a GOD fearing man, if you are in need of loan and you will pay back the loan please contact him tell him that is Mrs Anita, that refer you to him. contact Dr Purva Pius.View Email: urgentloan22@gmail.com

    ReplyDelete
  44. Hi Tom,

    Great tool! Is there a limit to the amount of items you can put in the inventory? I'm thinking of using this for the library at our kindergarten.
    Thank you, Gabriela

    ReplyDelete
  45. This comment has been removed by the author.

    ReplyDelete
  46. Hi, Tom. Thank you very much for this tutorial. But, i have an issue and im not able to find the solution. Im getting ID error on Web App..

    could you please check it:

    https://script.google.com/d/1-G1qogtTujzpplV0wBarHR6PIa9QUsEi1f5211NOqnBwjriw3wv_9UqF/edit?usp=sharing

    https://docs.google.com/spreadsheets/d/1YDQVKAcuwTvGZVF08u3o93jGt7ItsRaomF4z4xTUuQI/edit?usp=sharing

    thanks!

    ReplyDelete
  47. Hi people,
    Thank you so much for this wonderful article really!
    If someone want to learn more about the product management methodology I think this is the right place for you!

    ReplyDelete
  48. Building robust, integrated, native applications is quickly becoming a requirement across the enterprise, but not having mobile programming skills in Objective C, Java, Javascript, and/or Mobile J Query no longer has to be a roadblock. Those developers with mobile programming experience can leverage their skills to extend development further and significantly faster than ever before. 

    Cado Magenge
    "http://appdevelopmentcompany.com.au/android-application-development.html"
    "http://www.appdevelopmentcompany.com.au/email-marketing.html"
    "http://appdevelopmentcompany.com.au/iphone-application-development.html"
    ”http://appdevelopmentcompany.com.au/ipad-application-development.html”

    ReplyDelete
  49. Building robust, integrated, native applications is quickly becoming a requirement across the enterprise, but not having mobile programming skills in Objective C, Java, Javascript, and/or Mobile J Query no longer has to be a roadblock. Those developers with mobile programming experience can leverage their skills to extend development further and significantly faster than ever before. 

    Cado Magenge
    "http://appdevelopmentcompany.com.au/android-application-development.html"
    "http://www.appdevelopmentcompany.com.au/email-marketing.html"
    "http://appdevelopmentcompany.com.au/iphone-application-development.html"
    ”http://appdevelopmentcompany.com.au/ipad-application-development.html”

    ReplyDelete
  50. Very helpful suggestions that help in the optimizing website.
    I really like you post.Thanks for sharing.
    goldenslot
    Gclub จีคลับ
    gclub casino

    ReplyDelete

Post a Comment

Popular posts from this blog

Inserting A Google Doc link into a Google Spreadsheet (UPDATED 6/12/2017)

This article looks at using Apps Script to add new features to a Google Spreadsheet.

At the University of York, various people have been using Google spreadsheets to collect together various project related information. We've found that when collecting lots of different collaborative information from lots of different people that a spreadsheet can work much better than a regular Google Form.

Spreadsheets can be better than Forms for data collection because:

The spreadsheet data saves as you are editing.If you want to fill in half the data and come back later, your data will still be there.The data in a spreadsheet is versioned, so you can see who added what and when and undo it if necessaryThe commenting features are brilliant - especially the "Resolve" button in comments.
One feature we needed was to be able to "attach" Google Docs to certain cells in a spreadsheet. It's easy to just paste in a URL into a spreadsheet cell, but they can often all look too si…

One-To-Many Relationship in a Google Spreadsheet

It's often the case that you want and need to be creating a database to store your data, but Google Spreadsheets are just so handy aren't they? But Google Spreadsheets are very good at relational data.

Here's an example where, you want to have one column for the name of your recipe and another for the ingredients ( comma separated ).

How you use this script is you click on the cell you want to be relational and choose the Admin > Show Relationship Editor. This opens up a dialog window showing you all the options included so far. You then alter the ingredients and it saves a comma separated list into the spreadsheet.







Here's the spreadsheet. Use File > Make a copy to see it work and rummage around in the code.

If anyone can help make the UI prettier I'd be grateful, thanks.