Open14

データ結合虎の巻

isocchi1123isocchi1123

function processSheet() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // 現在のスプレッドシートを取得
var basicSheet = ss.getSheetByName('基本情報');
var dataSheet = ss.getSheetByName('データ集計用');

// 基本情報シートの名前列を取得
var basicData = basicSheet.getRange(2, 1, basicSheet.getLastRow() - 1, 1).getValues();

// データ集計用のAM列を取得
var amData = dataSheet.getRange(2, 1, dataSheet.getLastRow() - 1, 1).getValues();

// データ集計用のPM列を取得
var pmData = dataSheet.getRange(2, 2, dataSheet.getLastRow() - 1, 1).getValues();

for (var i = 0; i < basicData.length; i++) {
var basicName = normalizeName(basicData[i][0]); // 名前の正規化

// AMデータ確認
var foundAM = false;
for (var j = 0; j < amData.length; j++) {
  var amName = normalizeName(amData[j][0]); // AMデータの名前を正規化
  if (basicName === amName) {
    basicSheet.getRange(i + 2, 2).setValue('AM'); // B列にAMをセット
    foundAM = true;
    break;
  }
}

// PMデータ確認(AMで見つからなかった場合のみ)
if (!foundAM) {
  for (var k = 0; k < pmData.length; k++) {
    var pmName = normalizeName(pmData[k][0]); // PMデータの名前を正規化
    if (basicName === pmName) {
      basicSheet.getRange(i + 2, 2).setValue('PM'); // B列にPMをセット
      break;
    }
  }
}

}
}

// 名前の正規化関数
function normalizeName(name) {
return name.replace(/\s*(.?)\s/g, '') // 地名部分を削除
.replace(/\s+/g, '') // 全角・半角スペースを無視
.trim(); // 前後の余分なスペースを削除
}

isocchi1123isocchi1123

function cleanupNames() {
var ss = SpreadsheetApp.getActiveSpreadsheet();

// 基本情報シートの処理
var basicInfoSheet = ss.getSheetByName("基本情報");
if (basicInfoSheet) {
var basicInfoRange = basicInfoSheet.getRange("A:A");
var basicInfoValues = basicInfoRange.getValues();

for (var i = 0; i < basicInfoValues.length; i++) {
  if (basicInfoValues[i][0]) {
    basicInfoValues[i][0] = basicInfoValues[i][0].replace(/\s+/g, '');
  }
}

basicInfoRange.setValues(basicInfoValues);

}

// データ集計用シートの処理
var dataSheet = ss.getSheetByName("データ集計用");
if (dataSheet) {
var dataRange = dataSheet.getRange("A:G");
var dataValues = dataRange.getValues();

for (var i = 0; i < dataValues.length; i++) {
  for (var j = 0; j < dataValues[i].length; j++) {
    if (dataValues[i][j]) {
      // スペースを削除し、括弧内の地名を削除
      dataValues[i][j] = dataValues[i][j].replace(/\s+/g, '').replace(/\([^)]*\)/g, '');
    }
  }
}

dataRange.setValues(dataValues);

}
}

isocchi1123isocchi1123

function cleanupNames() {
var ss = SpreadsheetApp.getActiveSpreadsheet();

// データ集計用シートの処理
var dataSheet = ss.getSheetByName("データ集計用");
if (dataSheet) {
var dataRange = dataSheet.getRange("A:G");
var dataValues = dataRange.getValues();

for (var i = 0; i < dataValues.length; i++) {
  for (var j = 0; j < dataValues[i].length; j++) {
    if (dataValues[i][j]) {
      // スペースを削除し、括弧内の地名を確実に削除
      dataValues[i][j] = dataValues[i][j]
        .replace(/\s+/g, '')  // スペースを削除
        .replace(/\([^)]+\)/g, '')  // 括弧とその中身を削除
        .replace(/([^)]+)/g, '');  // 全角括弧とその中身も削除
    }
  }
}

dataRange.setValues(dataValues);

}
}

isocchi1123isocchi1123


結合しやすくなるようにスプレッドシートをGASで加工してみました

isocchi1123isocchi1123

function matchAndTransferTimeSlot() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName('基本情報');
var sheet2 = ss.getSheetByName('データ集計用');

// 基本情報シートのデータ取得
var data1 = sheet1.getRange(2, 1, sheet1.getLastRow() - 1, 4).getValues();

// データ集計用シートのデータ取得
var data2_AM = sheet2.getRange(2, 1, sheet2.getLastRow() - 1, 1).getValues();
var data2_PM = sheet2.getRange(2, 2, sheet2.getLastRow() - 1, 1).getValues();

// 名前一致と時間帯の設定
for (var i = 0; i < data1.length; i++) {
var name1 = data1[i][0].trim();

// AMの時間帯と照らし合わせ
for (var j = 0; j < data2_AM.length; j++) {
  if (name1 === data2_AM[j][0].trim()) {
    sheet1.getRange(i + 2, 2).setValue('AM');
    break;
  }
}

// PMの時間帯と照らし合わせ
for (var k = 0; k < data2_PM.length; k++) {
  if (name1 === data2_PM[k][0].trim()) {
    sheet1.getRange(i + 2, 2).setValue('PM');
    break;
  }
}

}
}

isocchi1123isocchi1123

function matchAndTransferTimeSlot() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName('基本情報'); // 基本情報シート
var sheet2 = ss.getSheetByName('データ集計用'); // データ集計用シート

// 基本情報シートのデータ取得
var data1 = sheet1.getRange(2, 1, sheet1.getLastRow() - 1, 4).getValues(); // A2からD列まで(利用者名、時間帯、曜日、住所)

// データ集計用シートのデータ取得
var data2_AM = sheet2.getRange(2, 1, sheet2.getLastRow() - 1, 1).getValues(); // A列(AMの利用者名)
var data2_PM = sheet2.getRange(2, 2, sheet2.getLastRow() - 1, 1).getValues(); // B列(PMの利用者名)

// 名前一致と時間帯の設定
for (var i = 0; i < data1.length; i++) {
var name1 = data1[i][0]; // 基本情報シートの名前(A列)

// AMの時間帯と照らし合わせ
for (var j = 0; j < data2_AM.length; j++) {
  if (name1 === data2_AM[j][0]) {
    sheet1.getRange(i + 2, 2).setValue('AM'); // 時間帯列(B列)に 'AM' を設定
    break;
  }
}

// PMの時間帯と照らし合わせ
for (var k = 0; k < data2_PM.length; k++) {
  if (name1 === data2_PM[k][0]) {
    sheet1.getRange(i + 2, 2).setValue('PM'); // 時間帯列(B列)に 'PM' を設定
    break;
  }
}

}
}

isocchi1123isocchi1123

function matchAndTransferTimeSlot() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName('基本情報');
var sheet2 = ss.getSheetByName('データ集計用');

// 基本情報シートのデータ取得
var data1 = sheet1.getRange(2, 1, sheet1.getLastRow() - 1, 4).getValues();

// データ集計用シートのデータ取得
var data2_AM = sheet2.getRange(2, 1, sheet2.getLastRow() - 1, 1).getValues();
var data2_PM = sheet2.getRange(2, 2, sheet2.getLastRow() - 1, 1).getValues();

// 名前一致と時間帯の設定
for (var i = 0; i < data1.length; i++) {
var name1 = data1[i][0].trim();

// AMの時間帯と照らし合わせ
for (var j = 0; j < data2_AM.length; j++) {
  if (name1 === data2_AM[j][0].trim()) {
    sheet1.getRange(i + 2, 2).setValue('AM');
    break;
  }
}

// PMの時間帯と照らし合わせ
for (var k = 0; k < data2_PM.length; k++) {
  if (name1 === data2_PM[k][0].trim()) {
    sheet1.getRange(i + 2, 2).setValue('PM');
    break;
  }
}

}
}

isocchi1123isocchi1123

function removeLocationFromNames() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheet = ss.getSheetByName('データ集計用');

// データ集計用シートのA~G列を対象に処理
var dataRange = dataSheet.getRange(2, 1, dataSheet.getLastRow() - 1, 7); // A~G列のデータ取得
var dataValues = dataRange.getValues();

for (var i = 0; i < dataValues.length; i++) {
for (var j = 0; j < dataValues[i].length; j++) {
if (dataValues[i][j] && typeof dataValues[i][j] === 'string') { // 空白でない文字列の場合のみ処理
// 明示的に (地名) を探して削除
var startIndex = dataValues[i][j].indexOf('(');
var endIndex = dataValues[i][j].indexOf(')');
if (startIndex !== -1 && endIndex !== -1) {
// (地名) を削除して更新
dataValues[i][j] = dataValues[i][j].substring(0, startIndex).trim() + dataValues[i][j].substring(endIndex + 1).trim();
}
}
}
}

// クリーンアップされたデータを再設定
dataRange.setValues(dataValues);
}

isocchi1123isocchi1123

function matchAndTransferTimeSlotAndDays() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName('基本情報'); // 基本情報シート
var sheet2 = ss.getSheetByName('データ集計用'); // データ集計用シート

// 基本情報シートのデータ取得
var data1 = sheet1.getRange(2, 1, sheet1.getLastRow() - 1, 4).getValues(); // A2からD列まで(利用者名、時間帯、曜日、住所)

// データ集計用シートのデータ取得
var data2_AM = sheet2.getRange(2, 1, sheet2.getLastRow() - 1, 7).getValues(); // A列からG列まで(AMの利用者名と曜日)
var data2_PM = sheet2.getRange(2, 2, sheet2.getLastRow() - 1, 7).getValues(); // B列からH列まで(PMの利用者名と曜日)

// 名前一致と時間帯・曜日の設定
for (var i = 0; i < data1.length; i++) {
var name1 = normalizeName(data1[i][0]); // 基本情報シートの名前を正規化
var daysAM = [];
var daysPM = [];

// AMの時間帯と照らし合わせ
for (var j = 0; j < data2_AM.length; j++) {
  var name2_AM = normalizeName(data2_AM[j][0]); // データ集計用シートのAMの名前を正規化
  if (name1 === name2_AM) {
    daysAM = extractDays(data2_AM[j]); // AMの曜日を取得
    sheet1.getRange(i + 2, 2).setValue('AM'); // 時間帯列(B列)に 'AM' を設定
    break;
  }
}

// PMの時間帯と照らし合わせ
for (var k = 0; k < data2_PM.length; k++) {
  var name2_PM = normalizeName(data2_PM[k][0]); // データ集計用シートのPMの名前を正規化
  if (name1 === name2_PM) {
    daysPM = extractDays(data2_PM[k]); // PMの曜日を取得
    sheet1.getRange(i + 2, 2).setValue('PM'); // 時間帯列(B列)に 'PM' を設定
    break;
  }
}

// 曜日列(C列)に、AMとPMの曜日を結合して設定
var combinedDays = daysAM.concat(daysPM).join(',');
sheet1.getRange(i + 2, 3).setValue(combinedDays); // 曜日列(C列)に曜日を設定

}
}

// 名前を正規化する関数(スペースと地名部分を削除)
function normalizeName(name) {
return name.replace(/\s*(.?)\s/g, '') // (地名) を削除
.replace(/\s+/g, '') // 全角・半角スペースを削除
.trim(); // 前後の余分なスペースを削除
}

// 曜日を抽出する関数
function extractDays(rowData) {
var days = [];
var dayLabels = ['月', '火', '水', '木', '金', '土', '日'];
for (var i = 1; i <= 7; i++) { // A列が名前で、それ以降に曜日があるため
if (rowData[i]) {
days.push(dayLabels[i - 1]); // 該当する曜日を追加
}
}
return days;
}

isocchi1123isocchi1123

強化版(データ加工)
function matchAndTransferTimeSlotAndDays() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName('基本情報'); // 基本情報シート
var sheet2 = ss.getSheetByName('データ集計用'); // データ集計用シート

// 基本情報シートのデータ取得
var data1 = sheet1.getRange(2, 1, sheet1.getLastRow() - 1, 4).getValues(); // A2からD列まで(利用者名、時間帯、曜日、住所)

// データ集計用シートのデータ取得
var data2_AM = sheet2.getRange(2, 1, sheet2.getLastRow() - 1, 7).getValues(); // A列からG列まで(AMの利用者名と曜日)
var data2_PM = sheet2.getRange(2, 2, sheet2.getLastRow() - 1, 7).getValues(); // B列からH列まで(PMの利用者名と曜日)

var similarityThreshold = 2; // 許容するLevenshtein距離の閾値

// 名前一致と時間帯・曜日の設定
for (var i = 0; i < data1.length; i++) {
var name1 = normalizeName(data1[i][0]); // 基本情報シートの名前を正規化
var daysAM = [];
var daysPM = [];
var timeSlotSet = false;

// AMの時間帯と照らし合わせ
for (var j = 0; j < data2_AM.length; j++) {
  var name2_AM = normalizeName(data2_AM[j][0]); // データ集計用シートのAMの名前を正規化
  if (calculateLevenshteinDistance(name1, name2_AM) <= similarityThreshold) { // 類似度が閾値以内なら一致と見なす
    daysAM = extractDays(data2_AM[j]); // AMの曜日を取得
    sheet1.getRange(i + 2, 2).setValue('AM'); // 時間帯列(B列)に 'AM' を設定
    timeSlotSet = true;
    break;
  }
}

// PMの時間帯と照らし合わせ
if (!timeSlotSet) { // AMで見つからなかった場合のみ
  for (var k = 0; k < data2_PM.length; k++) {
    var name2_PM = normalizeName(data2_PM[k][0]); // データ集計用シートのPMの名前を正規化
    if (calculateLevenshteinDistance(name1, name2_PM) <= similarityThreshold) { // 類似度が閾値以内なら一致と見なす
      daysPM = extractDays(data2_PM[k]); // PMの曜日を取得
      sheet1.getRange(i + 2, 2).setValue('PM'); // 時間帯列(B列)に 'PM' を設定
      timeSlotSet = true;
      break;
    }
  }
}

// 曜日列(C列)に、AMとPMの曜日を結合して設定
var combinedDays = daysAM.concat(daysPM).join(',');
if (combinedDays) {
  sheet1.getRange(i + 2, 3).setValue(combinedDays); // 曜日列(C列)に曜日を設定
} else {
  sheet1.getRange(i + 2, 3).setValue("未設定"); // 曜日が見つからなかった場合に "未設定" と表示
}

}
}

// 名前を正規化する関数(スペースと地名部分を削除)
function normalizeName(name) {
return name ? name.replace(/\s*(.?)\s/g, '').replace(/\s+/g, '').trim() : ''; // 空欄対応
}

// Levenshtein距離を計算する関数
function calculateLevenshteinDistance(a, b) {
var tmp;
if (a.length === 0) { return b.length; }
if (b.length === 0) { return a.length; }
if (a.length > b.length) { tmp = a; a = b; b = tmp; }

var i, j, res, alen = a.length, blen = b.length, row = Array(alen);
for (i = 0; i <= alen; i++) { row[i] = i; }

for (i = 1; i <= blen; i++) {
res = i;
for (j = 1; j <= alen; j++) {
tmp = row[j - 1];
row[j - 1] = res;
res = b[i - 1] === a[j - 1] ? tmp : Math.min(tmp + 1, Math.min(res + 1, row[j] + 1));
}
}
return res;
}

// 曜日を抽出する関数
function extractDays(rowData) {
var days = [];
var dayLabels = ['月', '火', '水', '木', '金', '土', '日'];
for (var i = 1; i <= 7; i++) { // A列が名前で、それ以降に曜日があるため
if (rowData[i]) {
days.push(dayLabels[i - 1]); // 該当する曜日を追加
}
}
return days;
}