Connecting a VB.NET application with a Google Docs Spreadsheet - vb.net

I'm creating a small application that can order stuff. The way a user can order something is to input the correct information through a google form, which then would be automatically converted to a Google Spreadsheet.
Now, I want to connect it to my VB application. How can I do that?

You should install sheetsapi v4 to your app.
Here is the code:
Public Class Form3
Shared Scopes As String() = {SheetsService.Scope.SpreadsheetsReadonly}
Shared ApplicationName As String = "Google Sheets API .NET Quickstart"
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim credential As UserCredential
Using stream = New FileStream("client_secret.json", FileMode.Open, FileAccess.Read)
Dim credPath As String = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)
credPath = Path.Combine(credPath, ".credentials/sheets.googleapis.com-dotnet-quickstart.json")
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets, Scopes, "user", CancellationToken.None, New FileDataStore(credPath, True)).Result
Console.WriteLine(Convert.ToString("Credential file saved to: ") & credPath)
End Using
Dim service = New SheetsService(New BaseClientService.Initializer() With { _
.HttpClientInitializer = credential, _
.ApplicationName = ApplicationName })
Dim spreadsheetId As [String] = "your sheet id"
Dim range As [String] = "A2:F"
Dim request As SpreadsheetsResource.ValuesResource.GetRequest = service.Spreadsheets.Values.[Get](spreadsheetId, range)
Dim response As ValueRange = request.Execute()
Dim values As IList(Of IList(Of [Object])) = response.Values
Dim son As String
If values IsNot Nothing AndAlso values.Count > 0 Then
ListBox1.Items.Add("Name, Major")
For Each rol In values
son = rol(0) + " " + rol(1) + " " + rol(2) + " " + rol(4)
' Print columns A and E, which correspond to indices 0 and 4.
ListBox1.Items.Add(son)
Next
End If
End Sub
End Class

Related

Google Sheets API V4 VB Net BatchUpdate - Upload

I am attempting to load the contents of a CSV file directly to an existing Google Sheet using the batch update method.
The problem is that my code is only uploading the last record, but from what I can tell the request object has all the data.
So far I am able to loop through the CSV file and cast each row to a Google Sheets ValueRange and add each ValueRange to a data object in order to apply it to the RequestBody required by the Google Sheets API.
This is all based on the API documentation available from Google.
Google Sheets API V4 Batch Update
I tossed in a few Message Boxes just to see what is happening in the background.
Below is the code I am using currently, and a sample set of data you can put into a csv file to run.
It appears that I am missing something with the upload request itself, if anyone has any input or experience with this I can't seem to get past this.
*Note: this code is simply a VB .Net winform app with a single button added to the form.
Imports System.Threading
Imports Google.Apis.Sheets.v4
Imports Google.Apis.Auth.OAuth2
Imports Google.Apis.Services
Imports Microsoft.VisualBasic.FileIO
Imports Google.Apis.Sheets.v4.Data
Imports Data = Google.Apis.Sheets.v4.Data
Public Class Form1
Dim ClientID As String = "<GOOGLE CLIENT>.apps.googleusercontent.com"
Dim ClientSecret As String = "<CLIENT SECRET>"
Dim Scopes As String() = {SheetsService.Scope.Spreadsheets}
Dim credential As UserCredential = GoogleWebAuthorizationBroker.AuthorizeAsync(New ClientSecrets() With {.ClientId = ClientID,
.ClientSecret = ClientSecret},
Scopes, "user",
CancellationToken.None).Result
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim r As Integer = 1
Dim oblist = New List(Of Object)
Dim sheetsService As SheetsService = New SheetsService(New BaseClientService.Initializer With {
.HttpClientInitializer = credential,
.ApplicationName = "Google-SheetsSample/0.1"
})
Dim spreadsheetId As String = "<SPREADSHEET ID>"
Dim valueInputOption As String = "RAW"
Dim valueRanges As ValueRange = New ValueRange()
Dim data As List(Of Data.ValueRange) = New List(Of Data.ValueRange)
Dim tfp As New TextFieldParser("<PATH TO CSV FILE I WANT TO UPLOAD>")
tfp.SetDelimiters(",")
tfp.TextFieldType = FieldType.Delimited
'tfp.ReadLine() ' skip header
While tfp.EndOfData = False
Dim fields = tfp.ReadFields()
Dim range2 As String = "A" & r ' range to update
valueRanges.MajorDimension = "ROWS" '"ROWS";//COLUMNS
valueRanges.Range = range2 ' apply range to ValueRnage
' My csv has 12 fields
oblist = New List(Of Object)() From {
fields(0), fields(1), fields(2), fields(3), fields(4), fields(5), fields(6), fields(7), fields(8), fields(9), fields(10), fields(11)
}
valueRanges.Values = New List(Of IList(Of Object)) From { ' add list of objects pulled from TextFieldParser to ValueRange
oblist
}
data.Add(valueRanges) ' Add valueRange to data for RequestBody
r += 1 ' Increment Range
End While
MsgBox("Count of value ranges in data object : " & data.Count)
Dim requestBody As Data.BatchUpdateValuesRequest = New Data.BatchUpdateValuesRequest()
requestBody.ValueInputOption = valueInputOption
requestBody.Data = data
MsgBox("Request body data : " & requestBody.Data.Count)
Dim request As SpreadsheetsResource.ValuesResource.BatchUpdateRequest = sheetsService.Spreadsheets.Values.BatchUpdate(requestBody, spreadsheetId)
Dim response As Data.BatchUpdateValuesResponse = request.Execute()
MsgBox("Count of Rows uploaded to google sheet : " & response.TotalUpdatedRows)
End Sub
End Class
CSV - EXAMPLE -
Column 1,Column 2,Column 3,Column 4,Column 5,Column 6,Column 7,Column 8,Column 9,Column 10,Column 11,Column 12
ex12,ex34,ex56,ex78,ex100,ex122,ex144,ex166,ex188,ex210,ex232,ex254
ex13,ex35,ex57,ex79,ex101,ex123,ex145,ex167,ex189,ex211,ex233,ex255
ex14,ex36,ex58,ex80,ex102,ex124,ex146,ex168,ex190,ex212,ex234,ex256
ex15,ex37,ex59,ex81,ex103,ex125,ex147,ex169,ex191,ex213,ex235,ex257
ex16,ex38,ex60,ex82,ex104,ex126,ex148,ex170,ex192,ex214,ex236,ex258
ex17,ex39,ex61,ex83,ex105,ex127,ex149,ex171,ex193,ex215,ex237,ex259
ex18,ex40,ex62,ex84,ex106,ex128,ex150,ex172,ex194,ex216,ex238,ex260
ex19,ex41,ex63,ex85,ex107,ex129,ex151,ex173,ex195,ex217,ex239,ex261
ex20,ex42,ex64,ex86,ex108,ex130,ex152,ex174,ex196,ex218,ex240,ex262
ex21,ex43,ex65,ex87,ex109,ex131,ex153,ex175,ex197,ex219,ex241,ex263
Here I create one code .. The difference is only you pass List to ValueRange whereas there should be IList ..
But for conversion from list to Ilist I used objList.ToList () and I don't know it's drawback you need to check
And also you have to create new object of valueRange within while loop
Dim sheetId = FileId
Dim service = GetGoogleAPPSheetService()
Dim val_range As ValueRange
Dim DataList As List(Of ValueRange) = New List(Of ValueRange)
Dim I As Integer = 0
Dim objList As List(Of Object)
Dim objMainList As List(Of IList(Of Object))
Dim objIlIst As IList(Of Object)
Dim objImainList As IList(Of IList(Of Object))
For Each dr As DataRow In dt.Rows
I += 1
val_range = New ValueRange
val_range.Range = "A" & I.ToString
objList = New List(Of Object) From {dr(0).ToString, dr(1).ToString}
objMainList = New List(Of IList(Of Object)) From {objList.ToList()}
val_range.Values = objMainList.ToList
DataList.Add(val_range)
Next
Dim req_body As BatchUpdateValuesRequest = New BatchUpdateValuesRequest
req_body.ValueInputOption = "RAW"
req_body.Data = DataList.ToList
Dim request As SpreadsheetsResource.ValuesResource.BatchUpdateRequest = service.Spreadsheets.Values.BatchUpdate(req_body, sheetId)
Dim response As BatchUpdateValuesResponse = request.Execute
MsgBox("Count of Rows uploaded to google sheet : " & response.TotalUpdatedRows)
Catch ex As Exception
Throw ex
End Try

How should I generate a "secret" code for my two factor authentication system?

I am only doing this as a method to secure a third party product that does not have a native way of requesting and setting up 2FA. Essentially this creates a request that is sent to IT to have them manually add the secret key to a users profile when requested.
How should I generate a "secret" code for my two factor authentication system?
I'm using the QRCoder package to generate a nice displayable QR Code for my userbase. And it works great in the Microsoft Authenticator app, but both Authy and Google fail.
I suppose my random secret generator function is to blame?
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim generator As OneTimePassword = New OneTimePassword() With {
.Secret = GenerateRandomString(16),
.Issuer = "My Site",
.Label = "My Service",
.Type = OneTimePassword.OneTimePasswordAuthType.TOTP
}
Dim payload As String = generator.ToString()
Dim qrGenerator As QRCodeGenerator = New QRCodeGenerator()
Dim qrCodeData As QRCodeData = qrGenerator.CreateQrCode(payload, QRCodeGenerator.ECCLevel.Q)
Dim qrCode As QRCode = New QRCode(qrCodeData)
LiteralQRCode.Text = generator.Secret
Dim imgBarCode As New System.Web.UI.WebControls.Image()
imgBarCode.Height = 300
imgBarCode.Width = 300
Using bitMap As Bitmap = qrCode.GetGraphic(20)
Using ms As New MemoryStream()
bitMap.Save(ms, System.Drawing.Imaging.ImageFormat.Png)
Dim byteImage As Byte() = ms.ToArray()
imgBarCode.ImageUrl = "data:image/png;base64," + Convert.ToBase64String(byteImage)
End Using
plBarCode.Controls.Add(imgBarCode)
End Using
End Sub
Public Function GenerateRandomString(ByRef iLength As Integer) As String
Dim rdm As New Random()
Dim allowChrs() As Char = "ABCDEFGHIJKLOMNOPQRSTUVWXYZ0123456789".ToCharArray()
Dim sResult As String = ""
For i As Integer = 0 To iLength - 1
sResult += allowChrs(rdm.Next(0, allowChrs.Length))
Next
Return sResult
End Function
I ended up using OtpNet and using their Base32Encode function to get what I needed.
Hopefully this will help the next person who is attempting to work on a project that isn't exactly conventional.
Dim totp = KeyGeneration.GenerateRandomKey()
Dim generator As OneTimePassword = New OneTimePassword() With {
.Secret = Base32Encoding.ToString(totp),
.Issuer = "My Site",
.Label = "My Service",
.Type = OneTimePassword.OneTimePasswordAuthType.TOTP
}

Acessing Google Calendar API from Windows Service

I am writing a windows service application in Visual Studio (VB) that polls a users google calendar for any events that are happening within the next 5 minutes.
Ideally, I'd like my service to generate the credentials, but I don't think a windows service can pop up a browser page to authenticate someone. Currently I am generating the credentials in a specific location from a console app that can pop up a browser, and having the service look for credentials in that location. I'd like to get rid of the console app altogether, but if it's necessary I'll just run it in the batch file that installs the service.
The big issue I'm having is generating the credentials file (secondary concern), and more importantly refreshing it so it doesn't expire after an hour (primary concern).
Here is my windows service code (this works perfectly fine for the hour after I run my console app and allow access to my calendar):
Dim Scopes As String() = {CalendarService.Scope.CalendarReadonly}
Dim ApplicationName As String = "Google Calendar API .NET Quickstart"
Private Sub writeUpdateTimerEvent(source As Object, e As ElapsedEventArgs)
Dim credential As UserCredential
Try
Using stream = New FileStream("FILE PATH TO client_secret.json", FileMode.Open, FileAccess.Read)
Dim credPath As String = "FILE PATH TO WHERE MY CONSOLE APP IS STORING THE CREDENTIALS FILE"
credPath = Path.Combine(credPath, ".credentials/calendar-dotnet-quickstart.json")
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets, Scopes, "user", CancellationToken.None, New FileDataStore(credPath, True)).Result
If credential Is Nothing Then
credential.RefreshTokenAsync(CancellationToken.None)
End If
End Using
' Create Google Calendar API service.
Dim service = New CalendarService(New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = ApplicationName
})
' Define parameters of request.
Dim request As EventsResource.ListRequest = service.Events.List("primary")
request.TimeMin = DateTime.Now
request.TimeMax = DateTime.Now.AddMinutes(5)
request.ShowDeleted = False
request.SingleEvents = True
request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime
' List events.
Dim eventsString As String = ""
Dim events As Events = request.Execute()
If events.Items IsNot Nothing AndAlso events.Items.Count > 0 Then
'This is where I do my operations on events occuring in the next 5 minutes
EventLog1.WriteEntry("Event occuring within 5 minutes")
Else
EventLog1.WriteEntry("No event occuring within 5 minutes")
End If
Catch ex As Exception
EventLog1.WriteEntry("error grabbing events." & Environment.NewLine & ex.message)
End Try
End Sub
Here is my console app code (pretty much the same as above):
Module Module1
Dim Scopes As String() = {CalendarService.Scope.CalendarReadonly}
Dim ApplicationName As String = "Google Calendar API .NET Quickstart"
Sub Main()
Dim credential As UserCredential
Using stream = New FileStream("client_secret.json", FileMode.Open, FileAccess.Read)
Dim credPath As String = "SAME FILE PATH AS IN MY SERVICE"
credPath = Path.Combine(credPath, ".credentials/calendar-dotnet-quickstart.json")
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets, Scopes, "user", CancellationToken.None, New FileDataStore(credPath, True)).Result
Console.WriteLine(Convert.ToString("Credential file saved to: ") & credPath)
End Using
' Create Google Calendar API service.
Dim service = New CalendarService(New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = ApplicationName
})
' Define parameters of request.
Dim request As EventsResource.ListRequest = service.Events.List("primary")
request.TimeMin = DateTime.Now
request.ShowDeleted = False
request.SingleEvents = True
request.MaxResults = 10
request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime
' List events.
Dim events As Events = request.Execute()
Console.WriteLine("Upcoming events:")
If events.Items IsNot Nothing AndAlso events.Items.Count > 0 Then
For Each eventItem As Object In events.Items
Dim [when] As String = eventItem.Start.DateTime.ToString()
If [String].IsNullOrEmpty([when]) Then
[when] = eventItem.Start.[Date]
End If
Console.WriteLine("{0} ({1})", eventItem.Summary, [when])
Next
Console.WriteLine("You may now close this window.")
System.Environment.Exit(0)
Else
Console.WriteLine("No upcoming events found.")
End If
Console.Read()
End Sub
End Module
Got it working now, using a service account instead of a user account. No need for dealing with generating credentials or refreshing the token.
Dim serviceAccountEmail As [String] = ConfigurationManager.AppSettings("ServiceAcct")
Dim certificate = New X509Certificate2("key.p12", "notasecret", X509KeyStorageFlags.Exportable)
Dim credential1 As New ServiceAccountCredential(New ServiceAccountCredential.Initializer(serviceAccountEmail) With {
.Scopes = Scopes
}.FromCertificate(certificate))
Dim service = New CalendarService(New BaseClientService.Initializer() With {
.HttpClientInitializer = credential1,
.ApplicationName = ApplicationName
})

Authenticating to Web Service VB.Net

Hi I am trying to Authenticate to my web service and missing something..
My Service reference is called - MBSDKServiceLD
My Web Reference is called - LANDeskMBSDK
I have these connected in Visual Studio 2013 And are resolving methods in the code
Here is my code for the authentication but its not complete..
Option Explicit On
Imports System.Net
Dim objFSO As Object
Dim objExec As Object
Dim objNetwork As Object
Dim strComputer As String
Dim strUser As String
Dim User As String
Dim Password As String
Dim Domain As String
Dim URL As String
Dim Cred As String
Dim strTaskName As String
Dim strPackageName As String
Dim strDeliveryMethod As String
Dim strCustomGroup As String
Dim boolStartNow As Boolean
Dim WakeUpMachines As Boolean
Dim boolCommonTask As Boolean
Dim strAutoSync As String
Dim TaskID As String
Dim strConnection As New System.Data.SqlClient.SqlConnection
Dim LDWebService
Dim intTaskID As String
Dim LDService As Object
Dim strDeviceName As String
Sub RunLANDeskTask(ByVal sender As Object, ByVal LDService As MBSDKServiceLD.MBSDKSoap)
End Sub
Sub CreateTask
User = "username1"
Password = "password1"
Domain = "domain1"
URL = "http://myserver/MBSDKService/MsgSDK.asmx?WSDL"
Dim MyCredentails As New System.Net.CredentialCache()
Dim NetCred As New System.Net.NetworkCredential(User, Password, Domain)
MyCredentails.Add(New Uri(URL), "Basic", NetCred)
strPackageName = "Adobe Acrobat XI PRO"
strDeliveryMethod = "Standard push distribution"
Dim strTargetDevice As String
strTargetDevice = Nothing
strTaskName = strPackageName & " - " & DateTime.Now & " -Provisioning Task for" & " " & strComputer
Try
RunLANDeskTask(LANDeskMBSDK, LDService.CreateTask(strTaskName, strDeliveryMethod, strPackageName, False, False, strAutoSync).TaskID)
Catch ex As Exception
MsgBox("Error creating task")
End Try
End Sub
What comes after this part or have i got this totally wrong?
When I type LDService. I see all the methods so I am connecting to the reference in VS but not authenticating.
It should really be as simple as this (sorry it's in c#):
MyWebService svc = new MyWebService();
svc.Credentials = new System.Net.NetworkCredential(UserID, pwd);
bool result = svc.MyWebMethod();
The following might be helpful:
This is quite old, but the comments are good.
I've just found the following on MSDN, which looks like what you want:
localhost.Sample svc = new localhost.Sample();
try {
CredentialCache credCache = new CredentialCache();
NetworkCredential netCred =
new NetworkCredential( "Example", "Test$123", "sseely2" );
credCache.Add( new Uri(svc.Url), "Basic", netCred );
svc.Credentials = credCache;
Ok i got this working... But i have to run the code under an account that can access the Web service -
Dim URL As String = "http://server/MBSDKService/MsgSDK.asmx?WSDL"
Dim myService As New LANDeskMBDSK.MBSDK
myService.Url = URL
Dim CredCache As New System.Net.CredentialCache
CredCache.Add(New Uri(myService.Url), "Basic", Cred)
myService.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials

Uploading to Google drive using VBA?

I have an MS Access database which now requires me to 'attach' documents to it. My intention is to store the documents on Google Drive and have a link on the database for users to retrieve the documents.
As there are many users spread through different cities, it is not practical to require them to have synced Google Drive folders. All the users will need the ability to upload to the database/GD so my intention is to have a separate Google account for the database - with its own login details.
example:
User clicks button to upload file
Save as dialog box appears and user selects file
Database logs into its Google Drive and uploads selected file
Lots of problems with this though, the main one being that Google Drive does not support VBA.
If the user is logged into their own Gmail account, that will probably be another issue.
I came across this code for vb.net on another site.
Imports System
Imports System.Diagnostics
Imports DotNetOpenAuth.OAuth2
Imports Google.Apis.Authentication.OAuth2
Imports Google.Apis.Authentication.OAuth2.DotNetOpenAuth
Imports Google.Apis.Drive.v2
Imports Google.Apis.Drive.v2.Data
Imports Google.Apis.Util
Imports Google.Apis.Services
Namespace GoogleDriveSamples
Class DriveCommandLineSample
Shared Sub Main(ByVal args As String)
Dim CLIENT_ID As [String] = "YOUR_CLIENT_ID"
Dim CLIENT_SECRET As [String] = "YOUR_CLIENT_SECRET"
'' Register the authenticator and create the service
Dim provider = New NativeApplicationClient(GoogleAuthenticationServer.Description, CLIENT_ID, CLIENT_SECRET)
Dim auth = New OAuth2Authenticator(Of NativeApplicationClient)(provider, GetAuthorization)
Dim service = New DriveService(New BaseClientService.Initializer() With { _
.Authenticator = auth _
})
Dim body As New File()
body.Title = "My document"
body.Description = "A test document"
body.MimeType = "text/plain"
Dim byteArray As Byte() = System.IO.File.ReadAllBytes("document.txt")
Dim stream As New System.IO.MemoryStream(byteArray)
Dim request As FilesResource.InsertMediaUpload = service.Files.Insert(body, stream, "text/plain")
request.Upload()
Dim file As File = request.ResponseBody
Console.WriteLine("File id: " + file.Id)
Console.WriteLine("Press Enter to end this process.")
Console.ReadLine()
End Sub
Private Shared Function GetAuthorization(ByVal arg As NativeApplicationClient) As IAuthorizationState
' Get the auth URL:
Dim state As IAuthorizationState = New AuthorizationState( New () {DriveService.Scopes.Drive.GetStringValue()})
state.Callback = New Uri(NativeApplicationClient.OutOfBandCallbackUrl)
Dim authUri As Uri = arg.RequestUserAuthorization(state)
' Request authorization from the user (by opening a browser window):
Process.Start(authUri.ToString())
Console.Write(" Authorization Code: ")
Dim authCode As String = Console.ReadLine()
Console.WriteLine()
' Retrieve the access token by using the authorization code:
Return arg.ProcessUserAuthorization(authCode, state)
End Function
End Class
End Namespace
It was suggested that the IE library could be utilised to log into the Google Drive and the API calls made from the above to upload. I don't know how to do this. Somewhere else it was mentioned that a 'COM wrapper' may be suitable. I don't have experience with any coding other than VBA (self taught) so am struggling to understand what the next step should be.
If anyone has done something similar or can offer any advice, I would be grateful to hear from you.
This thread might be dead now but if you are working with forms in your database and the user needs to be attaching the files to a particular record displayed in a form with a unique identification number then this is definitely possible but you would have to do it in an external application written in .NET I can provide you with the necessary code to get you started, vb.net is very similar to VBA.
What you would need to do is create a windows form project and add references to Microsoft access core dll and download the nugget package for google drive api from nugget.
Imports Google
Imports Google.Apis.Services
Imports Google.Apis.Drive.v2
Imports Google.Apis.Auth.OAuth2
Imports Google.Apis.Drive.v2.Data
Imports System.Threading
Public Class GoogleDriveAuth
Public Shared Function GetAuthentication() As DriveService
Dim ClientIDString As String = "Your Client ID"
Dim ClientSecretString As String = "Your Client Secret"
Dim ApplicationNameString As String = "Your Application Name"
Dim secrets = New ClientSecrets()
secrets.ClientId = ClientIDString
secrets.ClientSecret = ClientSecretString
Dim scope = New List(Of String)
scope.Add(DriveService.Scope.Drive)
Dim credential = GoogleWebAuthorizationBroker.AuthorizeAsync(secrets, scope, "user", CancellationToken.None).Result()
Dim initializer = New BaseClientService.Initializer
initializer.HttpClientInitializer = credential
initializer.ApplicationName = ApplicationNameString
Dim Service = New DriveService(initializer)
Return Service
End Function
End Class
This code will authorise your drive service then you create a Public Shared Service As DriveService under your imports that can be used from any sub or function then call this function on your form load event like
Service = GoogleDriveAuth.GetAuthentication
Add a reference to your project to Microsoft Access 12.0 Object Library or whatever version you have
Then this piece of code will look at the form you want to get the value of the record no from and upload a file to your choice of folder
Private Sub UploadAttachments()
Dim NumberExtracted As String
Dim oAccess As Microsoft.Office.Interop.Access.Application = Nothing
Dim connectedToAccess As Boolean = False
Dim SelectedFolderIdent As String = "Your Upload Folder ID"
Dim CreatedFolderIdent As String
Dim tryToConnect As Boolean = True
Dim oForm As Microsoft.Office.Interop.Access.Form
Dim oCtls As Microsoft.Office.Interop.Access.Controls
Dim oCtl As Microsoft.Office.Interop.Access.Control
Dim sForm As String 'name of form to show
sForm = "Your Form Name"
Try
While tryToConnect
Try
' See if can connect to a running Access instance
oAccess = CType(Marshal.GetActiveObject("Access.Application"), Microsoft.Office.Interop.Access.Application)
connectedToAccess = True
Catch ex As Exception
Try
' If couldn't connect to running instance of Access try to start a running Access instance And get an updated version of the database
oAccess = CType(CreateObject("Access.Application"), Microsoft.Office.Interop.Access.Application)
oAccess.Visible = True
oAccess.OpenCurrentDatabase("Your Database Path", False)
connectedToAccess = True
Catch ex2 As Exception
Dim res As DialogResult = MessageBox.Show("COULD NOT CONNECT TO OR START THE DATABASE" & vbNewLine & ex2.Message, "Warning", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Warning)
If res = System.Windows.Forms.DialogResult.Abort Then
Exit Sub
End If
If res = System.Windows.Forms.DialogResult.Ignore Then
tryToConnect = False
End If
End Try
End Try
' We have connected successfully; stop trying
tryToConnect = False
End While
' Start a new instance of Access for Automation:
' Make sure Access is visible:
If Not oAccess.Visible Then oAccess.Visible = True
' For Each oForm In oAccess.Forms
' oAccess.DoCmd.Close(ObjectType:=Microsoft.Office.Interop.Access.AcObjectType.acForm, ObjectName:=oForm.Name, Save:=Microsoft.Office.Interop.Access.AcCloseSave.acSaveNo)
' Next
' If Not oForm Is Nothing Then
' System.Runtime.InteropServices.Marshal.ReleaseComObject(oForm)
' End If
' oForm = Nothing
' Select the form name in the database window and give focus
' to the database window:
' oAccess.DoCmd.SelectObject(ObjectType:=Microsoft.Office.Interop.Access.AcObjectType.acForm, ObjectName:=sForm, InDatabaseWindow:=True)
' Show the form:
' oAccess.DoCmd.OpenForm(FormName:=sForm, View:=Microsoft.Office.Interop.Access.AcFormView.acNormal)
' Use Controls collection to edit the form:
oForm = oAccess.Forms(sForm)
oCtls = oForm.Controls
oCtl = oCtls.Item("The Name Of The Control Where The Id Number Is On The Form")
oCtl.Enabled = True
' oCtl.SetFocus()
NumberExtracted = oCtl.Value
System.Runtime.InteropServices.Marshal.ReleaseComObject(oCtl)
oCtl = Nothing
' Hide the Database Window:
' oAccess.DoCmd.SelectObject(ObjectType:=Microsoft.Office.Interop.Access.AcObjectType.acForm, ObjectName:=sForm, InDatabaseWindow:=True)
' oAccess.RunCommand(Command:=Microsoft.Office.Interop.Access.AcCommand.acCmdWindowHide)
' Set focus back to the form:
' oForm.SetFocus()
' Release Controls and Form objects:
System.Runtime.InteropServices.Marshal.ReleaseComObject(oCtls)
oCtls = Nothing
System.Runtime.InteropServices.Marshal.ReleaseComObject(oForm)
oForm = Nothing
' Release Application object and allow Access to be closed by user:
If Not oAccess.UserControl Then oAccess.UserControl = True
System.Runtime.InteropServices.Marshal.ReleaseComObject(oAccess)
oAccess = Nothing
If NumberExtracted = Nothing Then
MsgBox("The Number Could Not Be Obtained From The Form" & vbNewLine & vbNewLine & "Please Ensure You Have The Form Open Before Trying To Upload")
Exit Sub
End If
If CheckForDuplicateFolder(SelectedFolderIdent, NumberExtracted + " - ATC") = True Then
CreatedFolderIdent = GetCreatedFolderID(NumberExtracted + " - ATC", SelectedFolderIdent)
DriveFilePickerUploader(CreatedFolderIdent)
Else
CreateNewDriveFolder(NumberExtracted + " - ATC", SelectedFolderIdent)
CreatedFolderIdent = GetCreatedFolderID(NumberExtracted + " - ATC", SelectedFolderIdent)
DriveFilePickerUploader(CreatedFolderIdent)
End If
Catch EX As Exception
MsgBox("The Number Could Not Be Obtained From The Form" & vbNewLine & vbNewLine & "Please Ensure You Have The Form Open Before Trying To Upload" & vbNewLine & vbNewLine & EX.Message)
Exit Sub
Finally
If Not oCtls Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(oCtls)
oCtls = Nothing
End If
If Not oForm Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(oForm)
oForm = Nothing
End If
If Not oAccess Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(oAccess)
oAccess = Nothing
End If
End Try
End
End Sub
Check For Duplicate Folders In The Destination Upload Folder
Public Function CheckForDuplicateFolder(ByVal FolderID As String, ByVal NewFolderNameToCheck As String) As Boolean
Dim ResultToReturn As Boolean = False
Try
Dim request = Service.Files.List()
Dim requeststring As String = ("'" & FolderID & "' in parents And mimeType='application/vnd.google-apps.folder' And trashed=false")
request.Q = requeststring
Dim FileList = request.Execute()
For Each File In FileList.Items
If File.Title = NewFolderNameToCheck Then
ResultToReturn = True
End If
Next
Catch EX As Exception
MsgBox("THERE HAS BEEN AN ERROR" & EX.Message)
End Try
Return ResultToReturn
End Function
Create New Drive Folder
Public Sub CreateNewDriveFolder(ByVal DirectoryName As String, ByVal ParentFolder As String)
Try
Dim body1 = New Google.Apis.Drive.v2.Data.File
body1.Title = DirectoryName
body1.Description = "Created By Automation"
body1.MimeType = "application/vnd.google-apps.folder"
body1.Parents = New List(Of ParentReference)() From {New ParentReference() With {.Id = ParentFolder}}
Dim file1 As Google.Apis.Drive.v2.Data.File = Service.Files.Insert(body1).Execute()
Catch EX As Exception
MsgBox("THERE HAS BEEN AN ERROR" & EX.Message)
End Try
End Sub
Get The Created Folder ID
Public Function GetCreatedFolderID(ByVal FolderName As String, ByVal FolderID As String) As String
Dim ParentFolder As String
Try
Dim request = Service.Files.List()
Dim requeststring As String = ("'" & FolderID & "' in parents And mimeType='application/vnd.google-apps.folder' And title='" & FolderName & "' And trashed=false")
request.Q = requeststring
Dim Parent = request.Execute()
ParentFolder = (Parent.Items(0).Id)
Catch EX As Exception
MsgBox("THERE HAS BEEN AN ERROR" & EX.Message)
End Try
Return ParentFolder
End Function
Drive File Picker Uploader To Upload Files Selected From A File Dialog Box To The Newly Created Folder
Public Sub DriveFilePickerUploader(ByVal ParentFolderID As String)
Try
ProgressBar1.Value = 0
Dim MimeTypeToUse As String
Dim dr As DialogResult = Me.OpenFileDialog1.ShowDialog()
If (dr = System.Windows.Forms.DialogResult.OK) Then
Dim file As String
Else : Exit Sub
End If
Dim i As Integer = 0
For Each file In OpenFileDialog1.FileNames
MimeTypeToUse = GetMimeType(file)
Dim filetitle As String = (OpenFileDialog1.SafeFileNames(i))
Dim body2 = New Google.Apis.Drive.v2.Data.File
body2.Title = filetitle
body2.Description = "J-T Auto File Uploader"
body2.MimeType = MimeTypeToUse
body2.Parents = New List(Of ParentReference)() From {New ParentReference() With {.Id = ParentFolderID}}
Dim byteArray = System.IO.File.ReadAllBytes(file)
Dim stream = New System.IO.MemoryStream(byteArray)
Dim request2 = Service.Files.Insert(body2, stream, MimeTypeToUse)
request2.Upload()
Next
Catch EX As Exception
MsgBox("THERE HAS BEEN AN ERROR" & EX.Message)
End Try
End Sub
Get The Mime Type Of The Files Being Uploaded
Public Shared Function GetMimeType(ByVal file As String) As String
Dim mime As String = Nothing
Dim MaxContent As Integer = CInt(New FileInfo(file).Length)
If MaxContent > 4096 Then
MaxContent = 4096
End If
Dim fs As New FileStream(file, FileMode.Open)
Dim buf(MaxContent) As Byte
fs.Read(buf, 0, MaxContent)
fs.Close()
Dim result As Integer = FindMimeFromData(IntPtr.Zero, file, buf, MaxContent, Nothing, 0, mime, 0)
Return mime
End Function
<DllImport("urlmon.dll", CharSet:=CharSet.Auto)> _
Private Shared Function FindMimeFromData( _
ByVal pBC As IntPtr, _
<MarshalAs(UnmanagedType.LPWStr)> _
ByVal pwzUrl As String, _
<MarshalAs(UnmanagedType.LPArray, ArraySubType:=UnmanagedType.I1, SizeParamIndex:=3)> ByVal _
pBuffer As Byte(), _
ByVal cbSize As Integer, _
<MarshalAs(UnmanagedType.LPWStr)> _
ByVal pwzMimeProposed As String, _
ByVal dwMimeFlags As Integer, _
<MarshalAs(UnmanagedType.LPWStr)> _
ByRef ppwzMimeOut As String, _
ByVal dwReserved As Integer) As Integer
End Function
Hopefully this helps you make a start I am 100% convinced this is achievable as I have already done this for my manager.
This reply might be late but just wanna share one of the approach!
I have done this successfully with VBA and the demo link is here
http://www.sfdp.net/thuthuataccess/demo/democAuth.rar?attredirects=0&d=1
With this, you can upload, download or delete a file with your GoogleDrive in Access..
Just Wininet + WinHTTP enough
Dang Dinh ngoc
Vietnam