データ結合虎の巻
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(); // 前後の余分なスペースを削除
}
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);
}
}
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);
}
}
結合しやすくなるようにスプレッドシートをGASで加工してみました
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;
}
}
}
}
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;
}
}
}
}
上が曜日、下が時間帯加工
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;
}
}
}
}
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);
}
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;
}
強化版(データ加工)
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;
}