it-swarm.dev

تحديد الصف الأخير في عمود واحد

لدي ورقة بها بيانات في cols A خلال H.

أحتاج إلى تحديد الصف الأخير في العمود A الذي يحتوي على بيانات (كل هذا متجاور - لا توجد فجوات في البيانات/الصفوف).

هناك أيضًا بيانات في الأعمدة الأخرى التي تحتوي على أكثر صفوف بيانات من العمود A ، لذلك أحتاج إلى عزل العمود فقط A. (و/أو مجرد مجموعة داخل العقيد A).

يمكنني القيام بذلك على مستوى جدول البيانات باستخدام

=COUNTA(A2:A100)

ومع ذلك ، في جميع عمليات البحث التي أجريتها حول حل Google Apps Script ، يبدو أن كل ما أجده هو متطلبات لأداء وظائف متعددة تشمل العشرات من سطور التعليمات البرمجية - بما في ذلك الكثير من i++ الأشياء ... التي يمكنني القيام بها بطريقة أقل تعقيدًا عن طريق الموازنة مباشرة من A1.

هل من الممكن أن يكون هناك طريقة خاصة بالعمود لتعديل هذه الطريقة؟

var aLast = ss.getDataRange().getNumRows();

إذا كانت العملية المعقدة هي المطلوب ، فليكن ذلك. لكنني أجد صعوبة في تخيل (وأكثر صعوبة في إيجاد!) حلاً أبسط.

لا أحد يهتم لتنوير لي (أو البوب ​​فقاعة بلدي)؟

46
5th4x4

ماذا عن استخدام خدعة JavaScript؟

var Avals = ss.getRange("A1:A").getValues();
var Alast = Avals.filter(String).length;

لقد استعارت هذه الفكرة من هذه الإجابة . --- Array.filter() الطريقة تعمل على صفيف Avals ، الذي يحتوي على جميع الخلايا الموجودة في العمود أ. من خلال التصفية في مُنشئ دالة أصلية ، نعود فقط إلى عناصر خالية.

هذا يعمل لعمود واحد فقط ؛ إذا كان النطاق يحتوي على أعمدة متعددة ، فسوف تتضمن نتيجة filter() خلايا من جميع الأعمدة ، وبالتالي تكون خارج الأبعاد المأهولة بالنطاق.

119
Mogsdad

على الرغم من عدم وجود صيغة مستقيمة ، إلا أنني لا أتوقع ذلك ، فهي لا تتطلب عشرات أسطر التعليمات البرمجية لمعرفة الصف الأخير في العمود A. جرب هذه الوظيفة البسيطة. استخدمه في خلية بالطريقة المعتادة التي تستخدم بها بعض الوظائف الأخرى =CountColA()

function CountColA(){
  var sheet = SpreadsheetApp.getActiveSheet();
  var data = sheet.getDataRange().getValues();
  for(var i = data.length-1 ; i >=0 ; i--){
    if (data[i][0] != null && data[i][0] != ''){
      return i+1 ;
    }
  }
}
11
Srik

سيحصل هذا على الصف الأخير في ورقة على أساس العمود A.

function getLastDataRow(sheet) {
  var lastRow = sheet.getLastRow();
  var range = sheet.getRange("A" + lastRow);
  if (range.getValue() !== "") {
    return lastRow;
  } else {
    return range.getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
  }              
}

هذا إصلاح @ mrityunjay-pandey الإجابة جزئيا الصحيح.

لتمديد هذه الإجابة للحصول على آخر صف وعمود ، يمكننا استخدام:

function columnToLetter(column) {
  var temp, letter = '';
  while (column > 0) {
    temp = (column - 1) % 26;
    letter = String.fromCharCode(temp + 65) + letter;
    column = (column - temp - 1) / 26;
  }
  return letter;
}

function letterToColumn(letter) {
  var column = 0, length = letter.length;
  for (var i = 0; i < length; i++) {
    column += (letter.charCodeAt(i) - 64) * Math.pow(26, length - i - 1);
  }
  return column;
}

function getLastDataColumn(sheet) {
  var lastCol = sheet.getLastColumn();
  var range = sheet.getRange(columnToLetter(lastCol) + "1");
  if (range.getValue() !== "") {
    return lastCol;
  } else {
    return range.getNextDataCell(SpreadsheetApp.Direction.PREVIOUS).getColumn();
  }              
}

function getLastDataRow(sheet) {
  var lastRow = sheet.getLastRow();
  var range = sheet.getRange("A" + lastRow);
  if (range.getValue() !== "") {
    return lastRow;
  } else {
    return range.getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
  }              
}

function run() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var [startRow, lastRow] = [2, getLastDataRow(sheet)];
  var [startCol, lastCol] = [1, getLastDataColumn(sheet)];
}
5
Al Johri

يمكنك القيام بذلك عن طريق الذهاب في الاتجاه المعاكس. بدءًا من الصف الأخير في جدول البيانات والارتفاع حتى تحصل على بعض القيمة. سيعمل هذا في جميع الحالات حتى إذا كان لديك بعض الصفوف الفارغة بينهما. رمز يشبه أدناه:

var iLastRowWithData = lastValue('A');
function lastValue(column) {
  var iLastRow = SpreadsheetApp.getActiveSheet().getMaxRows();
  var aValues = SpreadsheetApp.getActiveSheet().getRange(column + "2:" + column + lastRow).getValues();

  for (; aValues[iLastRow - 1] == "" && iLastRow > 0; iLastRow--) {}
  return iLastRow;
}
5
Akash Garg

بالنسبة إلى جداول البيانات الكبيرة جدًا ، يكون هذا الحل سريعًا للغاية:

function GoLastRow() {
  var spreadsheet = SpreadsheetApp.getActive();
  spreadsheet.getRange('A:AC').createFilter();
  var criteria = SpreadsheetApp.newFilterCriteria().whenCellNotEmpty().build();
  var rg = spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(1, criteria).getRange();

  var row = rg.getNextDataCell (SpreadsheetApp.Direction.DOWN);  

  LastRow = row.getRow();

  spreadsheet.getActiveSheet().getFilter().remove();

  spreadsheet.getActiveSheet().getRange(LastRow+1, 1).activate();

};
2
Luciano Pivi

لقد استخدمت getDataRegion

sheet.getRange(1, 1).getDataRegion(SpreadsheetApp.Dimension.ROWS).getLastRow()

لاحظ أن هذا يعتمد على أن البيانات مجاورة (حسب طلب البروتوكول الاختياري).

1
Simon Birt

شخصيا لدي مشكلة مماثلة وذهبت مع شيء مثل هذا:

function getLastRowinColumn (ws, column) {
  var page_lastrow = ws.getDataRange().getNumRows();
  var last_row_col = 0
  for (i=1; i<=page_lastrow;i++) {
    if (!(spread.getRange(column.concat("",i)).isBlank())) {last_row_col = i};
  }
  return last_row_col
}

إنه يبحث عن عدد الصفوف في ws والحلقات خلال كل خلية في العمود الخاص بك. عندما تعثر على خلية غير فارغة ، تقوم بتحديث موضع هذه الخلية في متغير last_row_col. له ميزة السماح لك بالحصول على أعمدة غير متجاورة ومعرفة الصف الأخير (على افتراض أنك تمر العمود بأكمله).

0
jello195

لم يفت الأوان لنشر إجابة بديلة آمل. إليك مقتطف من "البحث عن الخلية الأخيرة". أنا مهتم بالدرجة الأولى بالسرعة. على قاعدة بيانات أستخدمها مع حوالي 150،000 صفًا ، استغرقت هذه الوظيفة (في المتوسط) 0.087 ثانية لإيجاد حل مقارنة بحلMogsdad الأنيق JS أعلاه والذي يأخذ (متوسط) 0.53 ثانية على نفس البيانات. تم تحميل كلا الصفيفين مسبقًا قبل استدعاء الوظيفة. فإنه يجعل من استخدام العودية لإجراء بحث ثنائي. بالنسبة إلى أكثر من 100،000 صف ، يجب أن تجد أن الأمر لا يتطلب أكثر من 15 إلى 20 قفزة لإعادتها.

لقد تركت المكالمات في السجل حتى تتمكن من اختبارها في وحدة التحكم أولاً ومشاهدة أعمالها.

/* @OnlyCurrentDoc */

function myLastRow() {

var ss=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var colArray = ss.getRange('A1:A').getDisplayValues();  // Change to relevant column label and put in Cache
var TestRow=ss.getLastRow();
var MaxRow=ss.getMaxRows(); 

Logger.log ('TestRow = %s',TestRow);
Logger.log ('MaxRow = %s',MaxRow);

var FoundRow=FindLastRow(TestRow,MaxRow);

Logger.log ('FoundRow = %s',FoundRow);    

function FindLastRow(v_TestRow,v_MaxRow) {

/* Some Housekeeping/error trapping first
* 1) Check that LastRow doesn't = Max Rows. If so then suggest to add a few lines as this
* indicates the LastRow was the end of the sheet.
* 2) Check it's not a new sheet with no data ie, LastRow = 0 and/or cell A1 is empty.
* 3) A return result of 0 = an error otherwise any positive value is a valid result.
*/

 return   !(colArray[0][0]) ? 1                   // if first row is empty then presume it's a new empty sheet
        :!!(colArray[v_TestRow][0]) ? v_TestRow   // if the last row is not empty then column A was the longest
        : v_MaxRow==v_TestRow ? v_TestRow         // if Last=Max then consider adding a line here to extend row count, else
        : searchPair(0,v_TestRow);                // get on an find the last row
}

function searchPair(LowRow,HighRow){

var BinRow = ((LowRow+HighRow)/2)|0;   // force an INT to avoid row ambiguity

Logger.log ('LowRow/HighRow/BinRow = %s/%s/%s',LowRow, HighRow, BinRow);

/*   Check your log. You shoud find that the last row is always found in under 20 Hops.
 *   This will be true whether your data rows are 100 or 100,000 long.
 *   The longest element of this script is loading the Cache (ColArray)
 */

 return   (!(colArray[BinRow-1][0]))^(!(colArray[BinRow][0])) ? BinRow
        : (!(colArray[BinRow-1][0]))&(!(colArray[BinRow][0])) ? searchPair(LowRow,BinRow-1)
        : (!!(colArray[BinRow-1][0]))|(!!(colArray[BinRow][0])) ? searchPair(BinRow+1,HighRow)
        : false;   // Error
 }
}

/* The premise for the above logic is that the binary search is looking for a specific pairing, <Text/No text>
 * on adjacent rows.  You said there are no gaps so the pairing <No Text/Text> is not tested as it's irrelevant.
 * If the logic finds <No Text/No Text> then it looks back up the sheet, if it finds <Text/Text> it looks further
 * down the sheet.  I think you'll find this is quite fast, especially on datasets > 100,000 rows.
 */
0
DeeKay789

أعدت كتابة الدالتين getLastRow/getLastColumn لتحديد فهرس صف أو فهرس عمود.

function get_used_rows(sheet, column_index){
      for (var r = sheet.getLastRow(); r--; r > 0) {
        if (sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getCell(r, column_index).getValue() != ""){
          return r;
          break;
        }
      }
    }

function get_used_cols(sheet, row_index){
  for (var c = sheet.getLastColumn(); c--; c > 0) {
    if (sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getCell(row_index, c).getValue() != ""){
      return c;
      break;
    }
  }
}
0
Ashton Fei

تحديث من Mogsdad الحل ،

var Avals = ss.getRange("A1:A").getValues();
var Alast = Avals.filter(function(r){return r[0].length>0});
0
Tin Trang

حاولت كتابة 3 وظائف التالية ، يمكنك اختبارها لحالات مختلفة من لك. هذه هي البيانات التي اختبرتها مع:

enter image description here

الدالة getLastRow1 و getLastRow2 ستُرجع 0 للعمود B ستُرجع الدالة getLastRow3 1 للعمود B

حسب حالتك ، سوف تقوم بتعديلها حسب احتياجاتك.

function getLastRow1(sheet, column) {
  var data = sheet.getRange(1, column, sheet.getLastRow()).getValues();

  while(typeof data[data.length-1] !== 'undefined'
     && data[data.length-1][0].length === 0){ 
    data.pop();
  }
  return data.length;
}

function test() {
  var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet6');
  Logger.log('Cách 1');
  Logger.log("Dòng cuối cùng của cột A là: " + getLastRow1(sh, 1));
  Logger.log("Dòng cuối cùng của cột B là: " + getLastRow1(sh, 2));
  Logger.log("Dòng cuối cùng của cột C là: " + getLastRow1(sh, 3));
  Logger.log("Dòng cuối cùng của cột D là: " + getLastRow1(sh, 4));
  Logger.log("Dòng cuối cùng của cột E là: " + getLastRow1(sh, 5));
  Logger.log('Cách 2');  
  Logger.log("Dòng cuối cùng của cột A là: " + getLastRow2(sh, 1));
  Logger.log("Dòng cuối cùng của cột B là: " + getLastRow2(sh, 2));
  Logger.log("Dòng cuối cùng của cột C là: " + getLastRow2(sh, 3));
  Logger.log("Dòng cuối cùng của cột D là: " + getLastRow2(sh, 4));
  Logger.log("Dòng cuối cùng của cột E là: " + getLastRow2(sh, 5));
  Logger.log('Cách 3');
  Logger.log("Dòng cuối cùng của cột A là: " + getLastRow3(sh, 'A'));
  Logger.log("Dòng cuối cùng của cột B là: " + getLastRow3(sh, 'B'));
  Logger.log("Dòng cuối cùng của cột C là: " + getLastRow3(sh, 'C'));
  Logger.log("Dòng cuối cùng của cột D là: " + getLastRow3(sh, 'D'));
  Logger.log("Dòng cuối cùng của cột E là: " + getLastRow3(sh, 'E'));

}

function getLastRow2(sheet, column) {
  var lr = sheet.getLastRow();
  var data = sheet.getRange(1, column, lr).getValues();

  while(lr > 0 && sheet.getRange(lr , column).isBlank()) {
    lr--;
  }

  return lr;
}

function getLastRow3(sheet, column) {
  var lastRow = sheet.getLastRow();
  var range = sheet.getRange(column + lastRow);
  if (range.getValue() !== '') {
    return lastRow;
  } else {
    return range.getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
  } 
}
0
Đức Thanh Nguyễn

للحصول على عدد الأعمدة أو فهرس العمود الأخير:

var numColumns = sheet.getLastColumn()

للحصول على عدد الصفوف أو فهرس الصف الأخير:

var numRows = sheet.getLastRow()

أين

var sheet = SpreadsheetApp.getActiveSheet()
0
Ashish Verma
var Direction=SpreadsheetApp.Direction;
var aLast =ss.getRange("A"+(ss.getLastRow()+1)).getNextDataCell(Direction.UP).getRow();
0
Mrityunjay pandey

قد تكون هذه طريقة أخرى للالتفاف حول lastrow. قد تحتاج إلى الالتفاف على الكود ليناسب احتياجاتك

    function fill() {
      var spreadsheet = SpreadsheetApp.getActive();
      spreadsheet.getRange('a1').activate();
      var lsr = spreadsheet.getLastRow();
      lsr=lsr+1;
      lsr="A1:A"+lsr;

      spreadsheet.getActiveRange().autoFill(spreadsheet.getRange(lsr), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
};
0
Tariq Khalaf