ChatGPT:n avustuksella tein funkkarit jotka pilkkovat jokaisen osakkeen transkatiot omalle sheetille. Toinen funkkari sitten laskee voiton/tappion per sheetti ja koostaa erillisen yhteenvetosheetin missä jokainen osake ja sen kaupoista tullut voitto tappio. Laskien ne verottajan haluamalla FIFO tavalla. Pistin tohon alle. Käytännössä noille kahdelle funktiolle voi tehdä Google Sheettiin napit, jota painamalla ne saa ajettua aina halutessaan.
Tämä siis ottaa sisään copy-pasten tuosta webbisivusta, joka menee suoraan Google Sheettiin.
@meta_meta_aly Et siis raportoinut tappiota per osake kuten verottaja kai jossain vaatii? Useinhan he eivät jaksa pikkusijoittajilta kaikkia kuluja kuulustella, jos rehellisen näköiset dokumentit on matkassa. Eli periaattessa tämä mun virittäminen turhaa. Toki opinhan tässä, että ChatGPT:n avulla pystyn tekemään JavaScript makroja Google Sheettiin. Hiukan riitelyä se kyllä vaati ja joku bugi piti ihan manuaalisestikin korjata. Silti paljon nopeampaan kuin ilman.
Alla kuva yhdestä rivistä josta näkyy miten sarakkeet on laitettu ja koodi.
EDIT: Korjattu bugi. Käytti vahingossa alkuperäisen valuutan saraketta. Vaihdettu J → K
function createSheetsForStocks() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var masterSheet = ss.getActiveSheet(); // Assumes the master sheet is the active sheet
var numRows = masterSheet.getLastRow() - 1; // Subtract 1 to exclude header row
var numCols = masterSheet.getLastColumn();
// Get header row
var header = masterSheet.getRange(1, 1, 1, numCols).getValues()[0];
// Get stock transaction data
var data = masterSheet.getRange(2, 1, numRows, numCols).getValues();
// Create a dictionary with stock names as keys and their transactions as values
var stocks = {};
data.forEach(function (transaction) {
var stockName = transaction[0];
if (!stocks[stockName]) {
stocks[stockName] = [];
}
stocks[stockName].push(transaction);
});
// Create separate sheets for each stock and copy the transactions to the new sheets
var stockSheets = [];
for (var stockName in stocks) {
var stockSheet = ss.getSheetByName(stockName);
if (!stockSheet) {
stockSheet = ss.insertSheet(stockName);
} else {
stockSheet.clear(); // Clear the sheet if it already exists
}
// Set the header row in the new sheet
stockSheet.getRange(1, 1, 1, numCols).setValues([header]);
// Reverse the order of transactions and write them to the new sheet
var transactions = stocks[stockName].reverse();
transactions.forEach(function (transaction, index) {
stockSheet.getRange(index + 2, 1, 1, numCols).setValues([transaction]);
});
// Auto-resize columns for better readability
stockSheet.autoResizeColumns(1, numCols);
stockSheets.push(stockSheet);
}
}
function calculateProfitLoss() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var masterSheet = ss.getActiveSheet(); // Assumes the master sheet is the active sheet
var sheets = ss.getSheets();
var profitSheet = ss.getSheetByName("Profit");
// If the Profit sheet doesn't exist, create it
if (!profitSheet) {
profitSheet = ss.insertSheet("Profit");
} else {
// Clear the entire Profit sheet
profitSheet.clear();
}
// Set the header row on the Profit sheet
profitSheet.getRange(1, 1, 1, 2).setValues([["Stock", "Total Profit/Loss"]]);
sheets.forEach(function (sheet, sheetIndex) {
if (sheet.getName() !== masterSheet.getName() && sheet.getName() !== "Profit") {
var numRows = sheet.getLastRow() - 1; // Subtract 1 to exclude header row
var transactions = sheet.getRange(2, 1, numRows, 15).getValues();
var buyQueue = [];
var totalProfitLoss = 0;
transactions.forEach(function (transaction, index) {
var units = transaction[6]; // Column G
var totalValue = transaction[10]; // Column K (changed from column O)
var profitLoss = 0;
if (units > 0) { // Buy
buyQueue.push({
units: units,
cost: totalValue / units,
});
} else { // Sale (units are negative)
var remainingUnits = -units;
var saleValue = totalValue / Math.abs(units);
while (remainingUnits > 0 && buyQueue.length > 0) {
var buy = buyQueue[0];
var unitsToSell = Math.min(buy.units, remainingUnits);
profitLoss += unitsToSell * (saleValue + buy.cost); // Changed - to + since buy.cost is negative
buy.units -= unitsToSell;
remainingUnits -= unitsToSell;
if (buy.units === 0) {
buyQueue.shift();
}
}
}
// Write the profit/loss value to column P
sheet.getRange(index + 2, 16).setValue(profitLoss);
totalProfitLoss += profitLoss;
});
// Write the stock name and total profit/loss to the Profit sheet
profitSheet.appendRow([sheet.getName(), totalProfitLoss]);
}
});
// Auto-resize columns for better readability
profitSheet.autoResizeColumns(1, 2);
}