Google Sheets PHP API: 'valueInputOption' is required but not specified - google-sheets

I'm having trouble because my code suddenly doesn't work.
I get the error "'valueInputOption' is required but not specified", when using the batchUpdate() function of the Sheets API.
I worked fine until now, but suddenly I get the above mentioned error.
You can see the complete response here https://analyse.sengeguruen.dk/micro.php
This is my code
private function writeUrlData() {
$totals = array( 'clicks' => 0,
'sales' => 0,
'revenue' => 0
);
if(isset($this->microData[$this->landingpage]) && is_array($this->microData[$this->landingpage]) && count($this->microData[$this->landingpage]) > 0) {
$cell_values = array();
$service = new Google_Service_Sheets($this->sheets_client);
/* Clear columns first*/
$cellsToClear = 'Micro-niveau!A2:E99999';
$clearRequestBody = new Google_Service_Sheets_ClearValuesRequest();
$clearResult = $service->spreadsheets_values->clear($this->spreadsheetId, $cellsToClear, $clearRequestBody);
$row_index = 2;
foreach($this->microData[$this->landingpage] as $program_id => $url_data) {
$clicks = isset($url_data['clicks']) ? $url_data['clicks'] : 0;
$sales = isset($url_data['sales']) ? $url_data['sales'] : 0;
$revenue = isset($url_data['revenue']) ? $url_data['revenue'] : 0;
$epc = $clicks > 0 ? round($revenue / $clicks, 2) : 0;
$program_name = $url_data['program_name'] != '' ? $url_data['program_name'] : $program_id;
$totals['clicks'] += $clicks;
$totals['sales'] += $sales;
$totals['revenue'] += $revenue;
$cell_values[] = new Google_Service_Sheets_ValueRange(array('range' => 'Micro-niveau!A'.$row_index.':E'.$row_index, 'values' => [[
$program_name,
$clicks,
$sales,
$revenue,
$epc
]]));
$row_index++;
}
// Insert row with totals
$cell_values[] = new Google_Service_Sheets_ValueRange(array('range' => 'Micro-niveau!A'.($row_index+1 ).':E'.($row_index+1), 'values' => [[
'Totals',
$totals['clicks'],
$totals['sales'],
$totals['revenue'],
round(($totals['revenue'] / $totals['clicks']), 2)
]]));
$batchBody = new Google_Service_Sheets_BatchUpdateValuesRequest([
'valueInputOption' => 'USER_ENTERED',
'data' => $cell_values
]);
try {
$batchResult = $service->spreadsheets_values->batchUpdate($this->spreadsheetId, $batchBody);
} catch (Exception $e) {
dump($e);
}
echo 'Done!';
}
}
I've tried finding solutions in older questions without any luck.

So I found out, that the issue was encoding of the text string for the variable $program_name.
So I changed the code to
private function writeUrlData() {
$totals = array( 'clicks' => 0,
'sales' => 0,
'revenue' => 0
);
if(isset($this->microData[$this->landingpage]) && is_array($this->microData[$this->landingpage]) && count($this->microData[$this->landingpage]) > 0) {
$cell_values = array();
$service = new Google_Service_Sheets($this->sheets_client);
/* Clear columns first*/
$cellsToClear = 'Micro-niveau!A2:E99999';
$clearRequestBody = new Google_Service_Sheets_ClearValuesRequest();
$clearResult = $service->spreadsheets_values->clear($this->spreadsheetId, $cellsToClear, $clearRequestBody);
$row_index = 2;
foreach($this->microData[$this->landingpage] as $program_id => $url_data) {
$clicks = isset($url_data['clicks']) ? $url_data['clicks'] : 0;
$sales = isset($url_data['sales']) ? $url_data['sales'] : 0;
$revenue = isset($url_data['revenue']) ? $url_data['revenue'] : 0;
$epc = $clicks > 0 ? round($revenue / $clicks, 2) : 0;
$program_name = $url_data['program_name'] != '' ? $url_data['program_name'] : $program_id;
$totals['clicks'] += $clicks;
$totals['sales'] += $sales;
$totals['revenue'] += $revenue;
$cell_values[] = new Google_Service_Sheets_ValueRange(array('range' => 'Micro-niveau!A'.$row_index.':E'.$row_index, 'values' => [[
utf8_encode($program_name),
$clicks,
$sales,
$revenue,
$epc
]]));
$row_index++;
}
// Insert row with totals
$cell_values[] = new Google_Service_Sheets_ValueRange(array('range' => 'Micro-niveau!A'.($row_index+1 ).':E'.($row_index+1), 'values' => [[
'Totals',
$totals['clicks'],
$totals['sales'],
$totals['revenue'],
round(($totals['revenue'] / $totals['clicks']), 2)
]]));
$batchBody = new Google_Service_Sheets_BatchUpdateValuesRequest([
'valueInputOption' => 'USER_ENTERED',
'data' => $cell_values
]);
try {
$batchResult = $service->spreadsheets_values->batchUpdate($this->spreadsheetId, $batchBody);
} catch (Exception $e) {
dump($e);
}
echo 'Done!';
}
}

Related

Array element from lua

I'm making a fivem server. But when i tru to pick the job.grade.name he says No grades.
QBShared.Jobs = {
["unemployed"] = {
label = "Werkloos",
grades = {
[0] = {
name = 'Werkloos',
payment = 10,
},
},
defaultDuty = true,
},
["police"] = {
label = "Politie",
grades = {
[0] = {
name = "Politie - Student", **Want to pick this**
payment = 200,
},
[1] = {
name = 'Aspirant',
payment = 300,
},
[2] = {
name = 'Agent',
payment = 400,
},
[3] = {
name = 'Hoofd Agent',
payment = 400,
},
[4] = {
name = 'Brigadier',
payment = 400,
},
[5] = {
name = 'Inspecteur',
payment = 400,
},
[6] = {
name = 'Hoofd Inspecteur',
payment = 400,
},
[7] = {
name = 'Commissaris',
payment = 400,
},
[8] = {
name = 'Hoofd Commissaris',
payment = 400,
},
[9] = {
name = 'Eerste Hoofd Commissaris',
isboss = true,
payment = 400,
},
},
defaultDuty = true,
So people can type /baan and then the see Baan: Politie
What i want is The must see Baan: Politie - Politie Student
QBCore.Commands.Add("baan", "Kijk wat je baan is", {}, false, function(source, args)
local Player = QBCore.Functions.GetPlayer(source)
TriggerClientEvent('chatMessage', source, "SYSTEM", "warning", "Baan: "..Player.PlayerData.job.label .. ' - ' ..Player.PlayerData.job.grade.name)
end)
Someone can help me? Because i want to learn more about lua but dont get this to work..
'Jobs' needs a string key to access it
and 'grades' needs a numerical index
Player .PlayerData .Jobs [job] .grades [grade] .name
TriggerClientEvent('chatMessage', source, "SYSTEM", "warning", "Baan: "..Player.PlayerData.job.label .. ' - ' ..Player.PlayerData.Jobs[job].grades[grade].name)
I'm assuming that somehow within your game engine, these values get parsed into PlayerData. That'll depend on the functions contained within fivem, and that you've used them properly. Otherwise, to access the raw table data, it's more like this:
print( QBShared.Jobs['police'].label )
Politie
print( QBShared.Jobs['police'].grades[0].name )
Politie - Student
print( QBShared.Jobs['police'].grades[0].payment )
200
if the game rearranges those during import into PlayerData, it might be
Player.PlayerData[job][grade].name
but it's very likely it remains in the original syntax illustrated above.

LINQ query with sub-query list

The query below should be selecting a list of information from different tables, and should also bring back a list of VehicleNames that are related to each ID coming back from db.Reservations
The query brings back data, but the list of VehicleNames only has one record, and it should bring back anywhere up to 5 records, depending on how many vehicles were reserved for that specific instance. I have tried adding a foreach to the VehicleName line in the select but I don't think I am using it right. Does anyone have any ideas as to how I can retrieve the list of values I need?
var query = from r in db.Reservations
let e = db.Employees.Where(x => r.RequestorID == x.ColleagueID).FirstOrDefault()
let rtv = db.ReservationToVehicle.Where(x => r.ID == x.ReservationID).FirstOrDefault()
let rs = db.ReservationStatus.Where(x => r.ID == x.ReservationID).FirstOrDefault()
let rst = db.ReservationStatusTypes.Where(x => rs.ReservationStatusTypeID == x.ID).FirstOrDefault()
select new
{
StartDate = r.StartDate,
EndDate = r.EndDate,
Destination = r.Destination,
PurposeOfTrip = r.PurposeOfTrip,
TransportingStudents = r.TransportStudentsFG,
EmployeeName = e.FirstName + " " + e.LastName,
ApprovalStatus = rst.StatusType,
ThemeColor = r.ThemeColor,
VehicleName = (from v in db.Vehicles
where v.ID == rtv.VehicleID
select v.VehicleName).ToList()
};
EDIT: Updated query, still uncertain how to get back list of Vehicles that have been reserved
var query = from r in db.Reservations
let e = db.Employees.Where(x => r.RequestorID == x.ColleagueID).FirstOrDefault()
let rtv = db.ReservationToVehicle.Where(x => r.ID == x.ReservationID).Select(y => y.VehicleID).ToList()
let rs = db.ReservationStatus.Where(x => r.ID == x.ReservationID).FirstOrDefault()
let rst = db.ReservationStatusTypes.Where(x => rs.ReservationStatusTypeID == x.ID).FirstOrDefault()
select new
{
StartDate = r.StartDate,
EndDate = r.EndDate,
Destination = r.Destination,
PurposeOfTrip = r.PurposeOfTrip,
TransportingStudents = r.TransportStudentsFG,
EmployeeName = e.FirstName + " " + e.LastName,
ApprovalStatus = rst.StatusType,
ThemeColor = r.ThemeColor,
VehicleName = (from v in db.Vehicles
where v.ID == rtv.VehicleID
select v.VehicleName).ToList()
};
rtv.VehicleID does not exist anymore, now rtv comes back with a list of IDs....I need to be able to get into that list to find where v.ID is IN the rtv list
Looks like people already told you this in the comments, but here's the code that ought to work:
var query = from r in db.Reservations
let e = db.Employees.Where(x => r.RequestorID == x.ColleagueID).FirstOrDefault()
let rtv = db.ReservationToVehicle.Where(x => r.ID == x.ReservationID).Select(y => y.VehicleID)
let rs = db.ReservationStatus.Where(x => r.ID == x.ReservationID).FirstOrDefault()
let rst = db.ReservationStatusTypes.Where(x => rs.ReservationStatusTypeID == x.ID).FirstOrDefault()
select new
{
StartDate = r.StartDate,
EndDate = r.EndDate,
Destination = r.Destination,
PurposeOfTrip = r.PurposeOfTrip,
TransportingStudents = r.TransportStudentsFG,
EmployeeName = e.FirstName + " " + e.LastName,
ApprovalStatus = rst.StatusType,
ThemeColor = r.ThemeColor,
VehicleName = (from v in db.Vehicles
where rtv.Contains(v.ID)
select v.VehicleName).ToList()
};
I'd also recommend looking at setting up navigation properties between your entities. Your query could be much simpler, something like this:
var query = from r in db.Reservations
let e = r.Requestor
let rs = r.ReservationStatus
let rst = rs.ReservationStatusType
select new
{
StartDate = r.StartDate,
EndDate = r.EndDate,
Destination = r.Destination,
PurposeOfTrip = r.PurposeOfTrip,
TransportingStudents = r.TransportStudentsFG,
EmployeeName = e.FirstName + " " + e.LastName,
ApprovalStatus = rst.StatusType,
ThemeColor = r.ThemeColor,
VehicleName = r.Vehicles.Select(v => v.VehicleName).ToList()
};

Can i use array with lambda notation?

Here is my Code :
string[] aa = new string[] { "Title", "Image", "Description" };
for (var i = 0; i <= 3; i++)
{
aa[i] = ems.SupportAdds.Where(x => x.ArticleId == id).Select(x => x.aa[i]).ToArray();
ViewBag.Collection[i] = aa[i];
}
I am getting error near x.aa[i].It is saying Table doesn't contain aa[i]. I want to use like that to short code. Please help me. I have its long version too which is working with my code.
Here is that one:
var Title = ems.SupportAdds.Where(x => x.ArticleId == id).Select(x => x.Title).ToArray();
ViewBag.Collection1 = Title;
var Description = ems.SupportAdds.Where(x => x.ArticleId == id).Select(x => x.Description).ToArray();
ViewBag.Collection2 = Description;
var Image = ems.SupportAdds.Where(x => x.ArticleId == id).Select(x => x.Image).ToArray();
ViewBag.Collection3 = Image;
And In view :
#Html.Raw(ViewBag.Collection2[i]
#Html.Raw(ViewBag.Collection2[i]
#Html.Raw(ViewBag.Collection3[i] // with increasing forloop which is working fine.
But I want to short it so I thought to use an array but it is not working with array. Can you guys suggest me the better way to write this code with lambda notation? Help will be appreciated.Thanks
I think you can improve performance by making changes like this
var allRecords= ems.SupportAdds.Where(x => x.ArticleId == id);
ViewBag.Collection1 = allRecords.Select(x => x.Title).ToArray();
ViewBag.Collection2 = allRecords.Select(x => x.Description).ToArray();
ViewBag.Collection3 = allRecords.Select(x => x.Image).ToArray();

Date Filter is not working properly MVC

My date filter works just fine when I put it into a separate view, but I am having trouble merging it with the other filters and I am not sure where I am going wrong. All other filters are working. Could you please take a look and let me know what I need to change when I join my query to the others to get it working and merged? Thank you!
Here is what it looks like in a separate Controller, and this works in the view:
public ActionResult DateFilter(FormCollection DatePicker)
{
DateTime start = DateTime.Today;
DateTime end = DateTime.Today;
if (DatePicker.Count > 0)
{
start = DateTime.Parse(DatePicker["startDate"].ToString());
end = DateTime.Parse(DatePicker["endDate"].ToString());
}
var Issue = db.Issue.Where(d => d.DateCreated >= start && d.DateCreated <= end).Select(i => new IssueViewModel
{
Name = i.Name,
Description = i.Description,
DateCreated = i.DateCreated,
DateCompleted = i.DateCompleted,
//ect.
}).ToList();
ViewBag.Issue = Issue;
return View();
}
Here is what it looks like merged with the other filters:
private static IQueryable<Issue> FilterDeviceList(List<Issue> issues, FormCollection DatePicker, string EHP, string IssueKey)
{
var query = issue.AsQueryable();
//COPYING STARTS HERE
DateTime start = DateTime.Today;
DateTime end = DateTime.Today;
if (DatePicker.Count > 0)
{
start = DateTime.Parse(DatePicker["startDate"].ToString());
end = DateTime.Parse(DatePicker["endDate"].ToString());
}
query = query.Where(d => d.DateCreated >= start != null && d.DateCreated <= end != null && d.DateCreated == Convert.ToDateTime(DatePicker));
//COPYING ENDS HERE
if (!string.IsNullOrWhiteSpace(EHP))
query = query.Where(i => i.EHPP != null && i.EHPP == (EHP == "1" ? false : true));
if (!string.IsNullOrWhiteSpace(IssueKey))
query = query.Where(i => i.IssueKey != null && i.IssueKey.Contains(IssueKey));
return query;
}
If anyone needs to see the view or the controller that calls IQueryable, please let me know and I can post it, but I think this should be sufficient. Thank you again! :)
Try this:
private static IQueryable<Issue> FilterDeviceList(List<Issue> issues, FormCollection DatePicker, string EHP, string IssueKey)
{
var query = issues.AsQueryable();
DateTime start,end;
if (DatePicker.Count > 0)
{
start = DateTime.ParseExact(DatePicker["startDate"].ToString(), "MM/dd/yyyy", CultureInfo.InvariantCulture);
end = DateTime.ParseExact(DatePicker["endDate"].ToString(), "MM/dd/yyyy", CultureInfo.InvariantCulture);
}
// assuming start and end date will not be null
if(start != null && end !=null)
{
query = query.Where(d => d.DateCreated >= start && d.DateCreated <= end);
}
if (!string.IsNullOrWhiteSpace(EHP))
query = query.Where(i => i.EHPP != null && i.EHPP == (EHP == "1" ? false : true));
if (!string.IsNullOrWhiteSpace(IssueKey))
query = query.Where(i => i.IssueKey != null && i.IssueKey.Contains(IssueKey));
return query;
}

getting the error: String reference not set to an instance of a String

When I filter records in a database by the date they were place, I want to be able to navigate through the filtered records across multiple pages. Right now, when I try to go to page 2 of the filtered records I receive the error:
String reference not set to an instance of a String.
Parameter name: s `
Also, I notice that the parameters that are passed in the url change. For example:
/PurchaseOrder?searchBy=Date&dateSearchBegin=08%2F15%2F2014&dateSearchEnd=09%2F01%2F2014&dateOrderedBegin=&dateOrderedEnd=&search=
becomes when I click page 2:
/PurchaseOrder?page=2&searchBy=Date
As it currently is written in my code I am using the Request.QueryString method to try to maintain the URL but it doesn't work for dates. Is there a method that is similar to this that I can use to fix this error and achieve my desired result?
Here is my code for the controller and the view:
Controller:
else if (searchBy == "Date")
{
if (dateSearchBegin == "" || dateSearchEnd == "")
{
//string message = "Both date fields are required";
}
else
{
var dtFrom = DateTime.Parse(dateSearchBegin);
var dtTo = DateTime.Parse(dateSearchEnd);
return View(db.PurchaseOrders.Where(x => x.Date >= dtFrom && x.Date <= dtTo).OrderBy(i => i.Date).ToPagedList(page ?? 1, 15));
}
}
else if (searchBy == "dateOrder")
{
if (dateOrderedBegin== ""|| dateOrderedEnd == "")
{
//string message = "Both date fields are required";
}
else
{
var dtFrom = DateTime.Parse(dateOrderedBegin);
var dtTo = DateTime.Parse(dateOrderedEnd);
return View(db.PurchaseOrders.Where(x => x.DateOrdered >= dtFrom && x.DateOrdered <= dtTo).OrderBy(i => i.Date).ToPagedList(page ?? 1, 15));
}
}
View:
#Html.PagedListPager(
Model, page => Url.Action("Index",
new { page, searchBy = Request.QueryString["searchBy"],
search = Request.QueryString["search"],
dtFrom = Request.QueryString["dtFrom"],
dtTo = Request.QueryString["dtTo"] }),
new PagedListRenderOptions() { DisplayPageCountAndCurrentLocation = true,
DisplayItemSliceAndTotal = true })
Your query string contains dateSearchBegin and dateSearchEnd and you are using dtFrom = Request.QueryString["dtFrom"], dtTo = Request.QueryString["dtTo"]
Change that to same keys in Url.Action() dateSearchBegin = Request.QueryString["dateSearchBegin "], dateSearchEnd = Request.QueryString["dateSearchEnd"]
Url.Action() will remove the null value query string args. One suggestion to check the string always use string.IsNullOrEmpty(strVar) do not use strVar == ""
"" != null. You're passing null to DateTime.Parse().
Change dateSearchBegin == "" to string.IsNullOrEmpty(dateSearchBegin) in order to prevent that.

Resources