FT not working propertly with Google Apps Script - oauth

I create a library with functions to insert data into a Fusion Table.This functions work fine.
Then, I create a new GAS proyect including this library. When I try to invoke the library function to insert data in FT, I always obtain "Authorizacion Requires". I grant the authorization all the times but it doesn't work (I'm the owner of all the GAS proyects and FT).
This is the url I see in Logs. The oAuth parameters are correct: UrlFetchApp.fetch([https://www.google.com/fusiontables/api/query, {oAuthServiceName=fusiontables, payload=sql=INSERT INTO 1MzzGAWuSZv_A1ETirCEHE8xWM5uBu7f3bJ0VPSc ('idProyecto','tipoNotificacion','idDocumento','fechaSolicitud','estado') values('dcccc','Eliminación IC','','Thu Aug 16 2012 13:36:41 GMT+0200 (CEST)','0'), oAuthUseToken=always, method=post}])
regards

Related

How to Call a Pkg/Procedure Executing an API From a Pkg/Procedure. The API name needs to be Dynamic and Has In and Out Parms

We use APIs, baninst1.PP_DEDUCTION.p_update and baninst1.PP_DEDUCTION.p_create, to maintain our payroll tables of benefit/deduction data. Numerous packages utilize the APIs. We would like to create a package containing the API call that all the existing packages can use and remove the code that is repeated in each package. I tried EXECUTE IMMEDIATE for the purpose of having a dynamic API name. However, I have not been able to get the syntax correct. I’m hoping you will help me.
create or replace PACKAGE BODY "ORBIT"."MM_BENEFITS_COMMON" AS
PROCEDURE PAY_P_EMPLOYEE_BENEFIT_ACTION(pi_benefit_action IN VARCHAR2,
                                                                               pi_pidm                   IN pdrbded.pdrbded_pidm%TYPE,
                                                                               pi_status                  IN pdrdedn.pdrdedn_status%TYPE,
                                                                               pi_bdca_code          IN pdrbded.pdrbded_bdca_code%TYPE,
                                                                               pi_effective_date     IN pdrdedn.pdrdedn_effective_date%TYPE DEFAULT NULL,                                                                               pi_user_id                IN pdrdedn.pdrdedn_user_id%TYPE DEFAULT NULL,                                                                               pi_data_origin          IN pdrdedn.pdrdedn_data_origin%TYPE DEFAULT NULL,
                                                                               po_base_rowid_out  OUT gb_common.internal_record_id_type,
                                                                               po_detail_rowid_out OUT gb_common.internal_record_id_type,
                                                                               pi_amount1              IN pdrdedn.pdrdedn_amount1%TYPE DEFAULT NULL,
                                                                               pi_opt_code1            IN pdrdedn.pdrdedn_opt_code1%TYPE DEFAULT NULL) IS
BEGIN
--Call the API for p_create or p_update.
baninst1.PP_DEDUCTION.pi_benefit_action(p_pidm                  => pi_pidm,
                                                                       p_status                 => pi_status,
                                                                       p_bdca_code          => pi_bdca_code,
                                                                       p_effective_date     => CASE
                                                                                                                 WHEN pi_benefit_action 'p_create' THEN
                                                                                                                       TRUNC(pi_begin_date)
                                                                                                                 ELSE
                                                                                                                       TRUNC(pi_effective_date)
                                                                                                             END,
                                                                      p_user_id                =>   pi_user_id,
                                                                      p_data_origin          =>   pi_data_origin,
                                                                      p_base_rowid_out   =>   po_base_rowid_out,
                                                                      p_detail_rowid_out  =>  po_detail_rowid_out,                                                                      p_amount1              =>  pi_amount1,
                                                                      p_opt_code1            => CASE
                                                                                                                 WHEN LENGTH(pi_opt_code1) = 1 THEN
                                                                                                                        '0' || pi_opt_code1
                                                                                                                 ELSE pi_opt_code1
                                                                                                            END);
END PAY_P_EMPLOYEE_BENEFIT_ACTION;
END MM_BENEFITS_COMMON;
create or replace PACKAGE BODY "ORBIT"."MM_BENEFIT_TEST" AS
PROCEDURE PAY_P_MM_BENEFIT_TEST IS
lv_base_rowid_out    gb_common.internal_record_id_type;
lv_detail_rowid_out   gb_common.internal_record_id_type;
BEGIN
--Pass data to the common benefits package for the api call
MM_BENEFITS_COMMON.PAY_P_EMPLOYEE_BENEFIT_ACTION('p_update', 9999999, 'A', 'VI1', '01-JAN-2022', 'MM_Test',     'MM_TEST', lv_base_rowid_out, lv_detail_rowid_out, 25.82, NULL);
END PAY_P_MM_BENEFIT_TEST;
END MM_BENEFIT_TEST;
I'm not sure what's bothering you, actually. You did post some code, but - I don't know what it represents.
Let's see what you said:
"We use APIs, baninst1.PP_DEDUCTION.p_update and baninst1.PP_DEDUCTION.p_create, to maintain our payroll tables of benefit/deduction data."
OK
"Numerous packages utilize the APIs."
it means that there are many packages and they call those p_update and p_create procedures; that's also OK
"We would like to create a package containing the API call that all the existing packages can use and remove the code that is repeated in each package."
that would be a new package; you'd cut that piece of code from all of your packages and paste it into a new one.
OK, makes sense. Instead of all that code (in every package), you'd put call to newly created procedures (that reside in a newly created package)
"I tried EXECUTE IMMEDIATE for the purpose of having a dynamic API name. However, I have not been able to get the syntax correct."
why dynamic SQL? There's nothing dynamic here. Instead of dozens of lines of code you currently have (that do something), you'd put one line - the one that calls that newly created procedure (and pass parameters)
From my point of view, there's nothing unusual in what you want to do and I can't imagine what problems you could have in doing it; it's pretty much straightforward.

Trying to access to a DBF file using Advantage OLE DB provider throws an exception when opening a connection

I have an ASP.NET MVC application which is trying to open below OLE DB connection:
string conString = #"Provider=Advantage OLE DB Provider;Data Source=" + dbfFilePath + ";Extended Properties=dBASE IV;";
using (dBaseConnection = new OleDbConnection(conString))
{
dBaseConnection.Open();
// Some stuff
}
I have installed below package from here.
I am using this provider in order to access a dbf file (specified on the dbfFilePath variable) and then later add some information into it. When I perform the Open command on the above code snippet I get below exception message:
Error 6420: The 'Discovery' process for the Advantage Database Server failed. Unable to connect to the Advantage Database Server. axServerConnect AdsConnect.
Previously I was using VFPOLEDB.4 provider and it was working ok when reading and modifying the dbf file. The problem is that it is only available in 32-bit (there is no version in 64-bit) and now I need it to be in 64-bit so I decided to use Advantage OLE DB provider that is available in 64-bit and as far as I know it does the same as VFPOLEDB.
What am I doing wrong?
UPDATE 2020/11/16:
If I add some parameters to connection string:
string conString = #"Provider=Advantage OLE DB Provider;Data Source=" + dbfFilePath + ";ServerType=ADS_LOCAL_SERVER;TableType=ADS_VFP;Extended Properties=dBASE IV;";
Then when opening connection I get below exception:
Error 7077: The Advantage Data Dictionary cannot be opened. axServerConnect AdsConnect
UPDATE 2020/11/20:
var dbfFilePath =#"C:\MyApp\Temp"; // using c:\MyApp\Temp\myTable.dbf does not work (below open command fails)
string conString = #"Provider=Advantage OLE DB Provider;Data Source=" + dbfFilePath + ";ServerType=ADS_LOCAL_SERVER; TableType=ADS_VFP;";
using (dBaseConnection = new OleDbConnection(conString))
{
dBaseConnection.Open();
OleDbCommand insertCommand = dBaseConnection.CreateCommand();
insertCommand.CommandText = "INSERT INTO [myTable] VALUES (2,100)";
insertCommand.ExecuteNonQuery();
}
Note: [myTable] has the same name that the dbf file within C:\MyApp\Temp.
Now open command works but when performing insertCommand.ExecuteNonQuery() it gets stuck (it does nothing).
UPDATE 2020/11/27:
Ok,I think I have detected what is happening. It works ok when using Advantage OLE DB provider in 32-bit, however, using Advantage OLE DB provider in 64-bit is not working. In both cases I use it on Windows Server 2012 R2 Standard 64-Bit and Advantage OLE DB provider is version 11.10.
I have checked this using LINQPad 5, and it works but when performing
insertCommand.ExecuteNonQuery()
... and before doing the insert to the dbf file below warning modal window appears waiting for you to click on 'Accept' button. Once you click on the button, insert is done in dbf file correctly.
So, I guess that when running my web application (ASP.NET MVC app) in production environment this warning modal windows does not appear but in fact, it is waiting for you to click on the button to proceed inserting data in the dbf file but as this warning window is not visible (it is not shown) I can click on that button and consequently ExecuteNonQuery never ends (it stalls) and it stays waiting for you to click that button indefinitely.
How can I solve this error? can I modify ads.ini in some way in order to avoid this waring message to appear so application can work?
I see you removed the VFP tag which I think most relevant to this question :)
I again tested that with these codes as a sample and it worked without a glitch:
void Main()
{
string dbfFilesPath = #"C:\PROGRAM FILES (X86)\MICROSOFT VISUAL FOXPRO 9\SAMPLES\Data";
string conString = $#"Provider=Advantage OLE DB Provider;Data Source={dbfFilesPath};ServerType=ADS_LOCAL_SERVER;TableType=ADS_VFP;";
DataTable t = new DataTable();
using (OleDbConnection cn = new OleDbConnection(conString))
using (OleDbCommand cmd = new OleDbCommand($#"insert into Customer
(cust_id, company, contact)
values
(?,?,?)", cn))
{
cmd.Parameters.Add("#cId", OleDbType.VarChar);
cmd.Parameters.Add("#company", OleDbType.VarChar);
cmd.Parameters.Add("#contact", OleDbType.VarChar);
cn.Open();
for (int i = 0; i < 10; i++)
{
cmd.Parameters["#cId"].Value = $"XYZ#{i}";
cmd.Parameters["#company"].Value = $"Company XYZ#{i}";
cmd.Parameters["#contact"].Value = $"Contact XYZ#{i}";
cmd.ExecuteNonQuery();
}
t.Load(new OleDbCommand($"select * from Customer order by cust_id desc", cn).ExecuteReader());
cn.Close();
}
t.Dump(); // tested in LinqPad AnyCPU version
}
Here is the partial result I got:
XYZ#9 Company XYZ#9 Contact XYZ#9 0.0000
XYZ#8 Company XYZ#8 Contact XYZ#8 0.0000
XYZ#7 Company XYZ#7 Contact XYZ#7 0.0000
XYZ#6 Company XYZ#6 Contact XYZ#6 0.0000
XYZ#5 Company XYZ#5 Contact XYZ#5 0.0000
XYZ#4 Company XYZ#4 Contact XYZ#4 0.0000
XYZ#3 Company XYZ#3 Contact XYZ#3 0.0000
XYZ#2 Company XYZ#2 Contact XYZ#2 0.0000
XYZ#1 Company XYZ#1 Contact XYZ#1 0.0000
XYZ#0 Company XYZ#0 Contact XYZ#0 0.0000
XXXXXX Linked Server Company 0.0000
WOLZA Wolski Zajazd Zbyszek Piestrzeniewicz Owner ul. Filtrowa 68 Warszawa 01-012 Poland (26) 642-7012 (26) 642-7012 3694
WINCA Wenna Wines Vladimir Yakovski Owner 0.0000
WILMK Wilman Kala Matti Karttunen Owner/Marketing Assistant Keskuskatu 45 Helsinki 21240 Finland 90-224 8858 90-224 8858 4400
WHITC White Clover Markets Karl Jablonski Owner 305 - 14th Ave. S., Suite 3B Seattle WA 98128 USA (206) 555-4112 (206) 555-4115 38900
WELLI Wellington Importadora Paula Parente Sales Manager Rua do Mercado, 12 Resende SP 08737-363 Brazil (14) 555-8122 3600
WARTH Wartian Herkku Pirkko Koskitalo Accounting Manager Torikatu 38 Oulu 90110 Finland 981-443655 981-443655 24200
As it is not working for you, I think it might have to do with:
Access rights. You say, you use with ASP.Net MVC, I wonder if the 'connecting account' has only read access? In IIS, basic settings as I remember there were a setting for connect as. You might at least set it to connect by an account that has full rights to that directory.
Sharing. The file might be in use shared elsewhere and for some reason your insert is waiting trying to get lock?
SET NULL ON ? Another slight possibility. You might need to execute this first, on the same connection. If there are fields that you are not supplying a value in insert but "not null" in table structure would otherwise cause it to fail.
You might start testing the same file from say within LinqPad running with administrator rights to eliminate the access rights stuff alltogether (if data directory is under program files or program files (x86), then it is a problem by itself.
I would expect an immediate error message, but who knows maybe driver is waiting for a timeout in case of write access failure?
Some ideas (the way I do it:)
Instead of trying to use VFP data with 64 bits access, you might create a server that runs in 32 bits IIS Application pool (or use its own web serving) and handles the data access via REST API (or WCF). I use 32 bits ASP.Net MVC application(s) since years with success using VFOLEDB itself.
If you think of REST API path, you might either use ASP.Net core (which is fast unlike the pre core) or use something else, say Go for building it. Go and Iris framework, for an example is an excellent fit to build a REST API server for your data over night (unlikely you would think Go, but if you do, remember to compile with x86 architecture).

How to get data from a SAP system using IDOC

I have currently install sap_netweaver_as_abap_751_sp02_ase_dev_edition and all works fine.
My final goal is to create some tables in SAP (I have SAP ASE installed as DB) and to be able to access them using java (of course with sapidoc3.jar and sapjco3.jar).
Until this moment I manage to create a connection to SAP and I get this output:
executing
Attributes:
DEST: mySAPSystem
OWN_HOST: HS-SW-05
PARTNER_HOST: vhcalnplci
SYSTNR: 00
SYSID: NPL
CLIENT: 001
USER: DEVELOPER
LANGUAGE: E
ISO_LANGUAGE: EN
OWN_CODEPAGE: 4102
OWN_CHARSET: UTF16
OWN_ENCODING: utf-16
OWN_BYTES_PER_CHAR: 2
PARTNER_CODEPAGE: 4103
PARTNER_CHARSET: UTF16
PARTNER_ENCODING: utf-16
PARTNER_BYTES_PER_CHAR: 2
OWN_REL: 721
PARTNER_REL: 751
PARTNER_TYPE: 3
KERNEL_REL: 749
TRACE:
RFC_ROLE: C
OWN_TYPE: E
CPIC_CONVID: 00000000
STFC_CONNECTION finished:
Echo: Hello SAP
Response: SAP R/3 Rel. 751 Sysid: NPL Date: 20180905 Time: 132841
Logon_Data: 001/DEVELOPER/E
I also manage to create a simple table in SAP, but right now I don't understand how can I receive info from that table using java and my jars(is not possible to make any selects or things like this).
From what I found on the internet I have understood that these tables are stored in an IDOC file and I should get somehow this IDOC.
If someone has done this before maybe can give me some clues about how can I get some date from a SAP database.
Thank you.
For now, I can only give a general answer, because I feel you'll have to search detailed guides through other posts, how IDOC works.
An IDOC is neither a table, nor a file. It's a format for exchanging data with SAP (SAP also stores them in IDOC tables, for logging and recovery purposes).
You can either send an IDOC to SAP, or get one from SAP. For instance, one IDOC could contain the data of a purchasing order.
To get data from SAP, you must push it from SAP, by defining:
some data in SAP (purchase order, customer, etc.),
when to send it (immediately or scheduled),
how to send the data via IDOCs to your "java program", by configuring partners and ports (file, HTTP, RFC...)
There are transaction codes like WE20, WE21, BD64.
On a trial system, there is almost no real application except the flight demo database. You may try filling it with the program SAPBC_DATA_GENERATOR, then use the program SAPBC_FILL_FLCUST_IDOC to send IDocs of type FLCUSTOMER_CREATEFROMDATA01.

How do I view the source code of a GW-BASIC .BAS file?

I have an old .BAS file that I'm trying to view and for which I'm running into some problems. Searching online seems to indicate that I should be able to just open it in NOTEPAD.EXE or similar, but doing so gives me gibberish, like this:
þ*©¿TÜ…7[/C̸yõ»€¹Ù<Ñ~Æ-$Ì™}³nFuJ,ÖYòÎg)ʇŒ~Š¯DËðïþSnhœJN
‰=É™2+df”c).vX»[šû'Û9¹8%ñx5m#8úV4ÊBº)Eª;Iú¹ó‹|àÆ„72#Ž§i§Ë #îÑ?
í‘ú™ÞMÖæÕjYе‘_¢y<…7i$°Ò.ÃÅR×ÒTÒç_yÄÐ
}+d&jQ *YòÎg)ʇŒ~Š¯DË?úŽ©Ž5\šm€S{ÔÍo—#ìôÔ”ÜÍѱ]ʵ¬0wêÂLª¡öm#Å„Ws雦 X
Ô¶æ¯÷¦É®jÛ ¼§
”n ŸëÆf¿´ó½4ÂäÌ3§Œ®
I know the file is sound, because I can open it in GW-BASIC. However, list does not seem to work to view the file, and trying to save the file in ASCII format from within GW-BASIC, didn't work either. Both just gave me an "Illegal function call" error:
GW-BASIC 3.22
(C) Copyright Microsoft 1983,1984,1986,1987
60300 Bytes free
Ok
LOAD"Pwrharm
Ok
LIST
Illegal function call
Ok
SAVE "Pwrharm2",A
Illegal function call
Ok
RUN
[Program runs successfully]
Then again, the run command works just fine. What am I doing wrong?
You're not doing anything wrong; the file was originally saved in GWBASIC with the ,P option. There is a 'hack' to unprotect it, described at https://groups.google.com/forum/#!topic/comp.os.msdos.misc/PA9sve0eKAk - basically, you create a file (call it UNPROT.BAS) containing only the characters 0xff 0x1a, then load the protected file, then load UNPROT.BAS, and you should then be able to list and save the program.
If you can't LIST or EDIT a GW-BASIC .BAS file that you LOADed from disk, it means that the file was originally SAVEd in protected format via SAVE filespec, P.
The 1988 "Handbook of BASIC - third edition" by David I. Schneider describes it as follows:
A program that has been SAVEd in protected format can be unprotected with the following technique.
(a) Create a file called RECOVER.BAS with the following program.
10 OPEN "RECOVER.BAS" FOR OUTPUT AS #1
20 PRINT #1, CHR$(255);
30 CLOSE #1
(b) LOAD the protected program into memory.
(c) Enter LOAD "RECOVER.BAS"
The formerly protected program will now be in memory and can be LISTed or EDITed, and reSAVEd in an unprotected format. This technique appears to work with most versions of BASIC. I have used it successfully with IBM PC BASIC, Compaq BASIC, and several versions of GW-BASIC. LOADing the file RECOVER.BAS will also restore a program after a NEW command has been executed.

How to get Excel version and macro security level

Microsoft has recently broken our longtime (and officially recommended by them) code to read the version of Excel and its current omacro security level.
What used to work:
// Get the program associated with workbooks, e.g. "C:\Program Files\...\Excel.exe"
SHELLAPI.FindExecutable( 'OurWorkbook.xls', ...)
// Get the version of the .exe (from it's Properties...)
WINDOWS.GetFileVersionInfo()
// Use the version number to access the registry to determine the security level
// '...\software\microsoft\Office\' + VersionNumber + '.0\Excel\Security'
(I was always amused that the security level was for years in an insecure registry entry...)
In Office 2010, .xls files are now associated with "“Microsoft Application Virtualization DDE Launcher," or sftdde.exe. The version number of this exe is obviously not the version of Excel.
My question:
Other than actually launching Excel and querying it for version and security level (using OLE CreateOLEObject('Excel.Application')), is there a cleaner, faster, or more reliable way to do this that would work with all versions starting with Excel 2003?
Use
function GetExcelPath: string;
begin
result := '';
with TRegistry.Create do
try
RootKey := HKEY_LOCAL_MACHINE;
if OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\excel.exe', false) then
result := ReadString('Path') + 'excel.exe';
finally
Free;
end;
end;
to get the full file name of the excel.exe file. Then use GetFileVersionInfo as usual.
As far as I know, this approach will always work.
using OLE CreateOLEObject('Excel.Application'))
you can get installed Excel versions by using the same registry place, that this function uses.
Basically you have to clone a large part of that function registry code.
You can spy on that function call by tools like Microsoft Process Monitor too see exactly how does Windows look for installed Excel - and then to do it exactly the same way.
You have to open registry at HKEY_CLASSES_ROOT\ and enumerate all the branches, whose name starts with "Excel.Application."
For example at this my workstation I only have Excel 2013 installed, and that corresponds to HKEY_CLASSES_ROOT\Excel.Application.15
But on my another workstation I have Excel 2003 and Excel 2010 installed, testing different XLSX implementations in those two, so I have two registry keys.
HKEY_CLASSES_ROOT\Excel.Application.12
HKEY_CLASSES_ROOT\Excel.Application.14
So, you have to enumerate all those branches with that name, dot, and number.
Note: the key HKEY_CLASSES_ROOT\Excel.Application\CurVer would have name of "default" Excel, but what "default" means is ambiguous when several Excels are installed. You may take that default value, if you do not care, or you may decide upon your own idea what to choose, like if you want the maximum Excel version or minimum or something.
Then when for every specific excel branch you should read the default key of its CLSID sub-branch.
Like HKEY_CLASSES_ROOT\Excel.Application.15\CLSID has nil-named key equal to
{00024500-0000-0000-C000-000000000046} - fetch that index to string variable.
Then do a second search - go into a branch named like HKEY_CLASSES_ROOT\CLSID\{00024500-0000-0000-C000-000000000046}\LocalServer ( use the fetched index )
If that branch exists - fetch the nil-named "default key" value to get something like C:\PROGRA~1\MICROS~1\Office15\EXCEL.EXE /automation
The last result is the command line. It starts with a filename (non-quoted in this example, but may be in-quotes) and is followed by optional command line.
You do not need command line, so you have to extract initial commanlind, quoted or not.
Then you have to check if such an exe file exists. If it does - you may launch it, if not - check the registry for other Excel versions.

Resources