Import fixed width text file using VBA into MS Access - ms-access

First and foremost, I am a novice at VBA. I am trying to use VBA, to import text files into MS Access tables. One of my challenges is the data is not always on the same lines of the text, but, the data is always the same columns and number of spaces. I'm tested several options, but, none efficient in any way. I have an old database, that does do the task, but, the code is hidden/locked, and the database is out of date, hence why I'm trying to recreate. Thank you in advance for any guidance.
Here's a sample of my text file report:
The data fields are (NAME, EMP, LVL, CODE1, CODE2, OFCC, COURSE CODE, NARRATIVE, DUR INTVL, STATUS, STATUS DATE, DUE DATE, EVTID)
DATA
TRAINING
INPUT IMAGE
TRAINING SECTION-PAGE: 1
ORG ID: 0001 BRANCH: OFFC1
SERIES/STEP COURSE DUR STATUS DUE
NAME EMP LVL CODE1 CODE2 OFCC CODE NARRATIVE INTVL STATUS DATE DATE EVT-ID
JOINES JAMES 57801 001 000A1 000A1 NIME 000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
PAGE 1
DATA
TRAINING
INPUT IMAGE
TRAINING SECTION-PAGE: 2
ORG ID: 0001 BRANCH: OFFC2
SERIES/STEP COURSE DUR STATUS DUE
NAME EMP LVL CODE1 CODE2 OFCC CODE NARRATIVE INTVL STATUS DATE DATE EVT-ID
GAINES JAMIE 45602 001 000A1 000A1 AIME 000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
PAGE 2
DATA
TRAINING
INPUT IMAGE
TRAINING SECTION-PAGE: 2
ORG ID: 0001 BRANCH: OFFC2
SERIES/STEP COURSE DUR STATUS DUE
NAME EMP LVL CODE1 CODE2 OFCC CODE NARRATIVE INTVL STATUS DATE DATE EVT-ID
JONESY CHADE 12303 001 000A1 000A1 AIME 000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
000001 COURSETITLE 001A *QUAL 01 JAN 17
PAGE 3
Here is one version of VBA that I tried to use to import a text file to a table in MS Access. I've had a couple of errors that I couldn't figure out, so I'm not sure if I'm going in the right direction.
Private Sub Command0_Click()
On Error GoTo Err_Command0_Click
'Requires reference to Microsoft Office 10.0 Object Library or later.
Dim varFile As Variant, db As Database, rec As Recordset
Dim sNAME As String, sEMP As String, sGRD As String
Dim sWC As String, sCOURSECODE As String, sNARRATIVE As String
Dim sSTATUS As String, dSTATUSDATE As Date, dDUEDATE As Date, sEVTID As String
'Set up the File Dialog.
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
With fDialog
.AllowMultiSelect = False
.Title = "Please select one file to import" 'Set the title of the dialog box.
.Filters.Clear
.Filters.Add "Text files", "*.txt", 1
'Show the dialog box. If the .Show method returns True, the user picked at least one file. If the .Show method returns False, the user clicked Cancel.
If .Show = True Then
For Each varFile In .SelectedItems
Set db = CurrentDb
DoCmd.SetWarnings False
DoCmd.RunSQL "Delete * from [TMA]"
DoCmd.SetWarnings True
Set rec = db.OpenRecordset("TMA")
Print #2, TextLine
With Text
'NAME
If Trim(Mid(TextLine, 1, 19)) = "" Then
.Cells(CurrentRow, 1) = Name
Else
.Cells(CurrentRow, 1) = Trim(Mid(TextLine, 1, 19))
Name = Trim(Mid(TextLine, 1, 19))
End If
'EMP
If Trim(Mid(TextLine, 21, 5)) = "" Then
.Cells(CurrentRow, 2) = EMP
Else
.Cells(CurrentRow, 2) = Trim(Mid(TextLine, 21, 5))
EMP = Trim(Mid(TextLine, 21, 5))
End If
'GRADE
If Trim(Mid(TextLine, 28, 3)) = "" Then
.Cells(CurrentRow, 3) = GRD
Else
.Cells(CurrentRow, 3) = Trim(Mid(TextLine, 28, 3))
GRD = Trim(Mid(TextLine, 28, 3))
End If
'WORK CENTER
If Trim(Mid(TextLine, 50, 4)) = "" Then
.Cells(CurrentRow, 4) = WC
Else
.Cells(CurrentRow, 4) = Trim(Mid(TextLine, 50, 4))
WC = Trim(Mid(TextLine, 50, 4))
End If
'COURSE CODE
If Trim(Mid(TextLine, 55, 6)) = "" Then
.Cells(CurrentRow, 5) = COURSECODE
Else
.Cells(CurrentRow, 5) = Trim(Mid(TextLine, 55, 6))
COURSECODE = Trim(Mid(TextLine, 55, 6))
'NARRATIVE
If Trim(Mid(TextLine, 62, 28)) = "" Then
.Cells(CurrentRow, 6) = NARRATIVE
Else
.Cells(CurrentRow, 6) = Trim(Mid(TextLine, 62, 28))
NARRATIVE = Trim(Mid(TextLine, 62, 28))
'STATUS
If Trim(Mid(TextLine, 96, 6)) = "" Then
.Cells(CurrentRow, 8) = STATUS
Else
.Cells(CurrentRow, 8) = Trim(Mid(TextLine, 96, 6))
STATUS = Trim(Mid(TextLine, 96, 6))
End If
'STATUS DATE
.Cells(CurrentRow, 9) = STATUSDATE
STATUSDATE = Trim(Mid(TextLine, 104, 9))
End If
'There isn't always a due date so keep going if it's blank
On Error Resume Next
'DUE DATE
.Cells(CurrentRow, 10) = DUEDATE
DUEDATE = Trim(Mid(TextLine, 114, 9))
On Error GoTo 0
'EVENT ID
If Trim(Mid(TextLine, 124, 7)) = "" Then
.Cells(CurrentRow, 4) = EVTID
Else
.Cells(CurrentRow, 4) = Trim(Mid(TextLine, 124, 7))
EVTID = Trim(Mid(TextLine, 124, 7))
End If
rec.AddNew
rec.Fields("NAME") = sNAME
rec.Fields("EMP") = sEMP
rec.Fields("GRD") = sGRD
rec.Fields("WC") = sWC
rec.Fields("COURSE CODE") = sCOURSECODE
rec.Fields("NARRATIVE") = sNARRATIVE
rec.Fields("STATUS") = sSTATUS
rec.Fields("STATUS DATE") = IIf(dSTATUSDATE = #12:00:00 AM#, vbNull, dSTATUSDATE)
rec.Fields("DUE DATE") = IIf(dDUEDATE = #12:00:00 AM#, vbNull, dDUEDATE)
rec.Fields("EVTID") = sEventID
rec.Update
Loop
rec.Close
db.Close
Next
Else
MsgBox "You clicked Cancel in the file dialog box."
End If
End With
Exit_Command0_Click:
DoCmd.SetWarnings False
DoCmd.RunSQL "UPDATE TMA SET TMA.STATUSDATE = """" WHERE (((TMA.STATUSDATE)=#12/31/1899#));"
DoCmd.RunSQL "UPDATE TMA SET TMA.DUEDATE = """" WHERE (((TMA.DUEDATE)=#12/31/1899#));"
DoCmd.SetWarnings True
Exit Sub
Err_Command0_Click:
MsgBox Err.Number & " " & Err.Description & " Check your Excel File for data consistancy with database structure. Ensure no text in date fields."
End If
If IsNull(rec) Then
rec.Close
End If
db.Close
Resume Exit_Command0_Click
End Sub

I would suggest using the Get External Data - Text File wizard to first import the file manually and save a specification file during the process. You can do this by clicking on the Advanced button upon reaching the last step of the wizard.
Then, use the DoCmd.TransferText method supplied with the name of the import specification that you saved earlier:
DoCmd.TransferText acImportFixed, "YourSavedSpecification", "YourTableName", "YourTextFilename", True
The last argument in this expression determines whether the import should expect your input file to include field names on the first row of the data - set this to false if this is not the case.

Without examples of your data file I can't provide any sample code here, so I am going to talk through in psuedo code. Your current approach is to filter the original data file which can be complex. My alternative approach is:
Import your text file (as-is) into a temporary table.
'// Use some very safe formats so all the text cells come in (e.g. treat all as strings and account for NULL values).
'// doesn't matter if the text in rows you don't care about don't come in cleanly.
Set up a Query to find the rows in this temporary table that meet your filter query.
Use the query result to fill your official table
'// Remember to convert from your safe import format into the data format you want.
This approach can be modularised (e.g. you can have tailored functions for different types of input files). The following shows the logic train (again, not based on executable code):
Function ImportTextFile(InFile as string) As Table
Function FindValidDataRows(TheSource as Table) As Query
Sub AppendtoData(TheQuery as Query)
Yes, the working level code may be similar to what you already have, but the maintainability and extensibility is greatly improved.

Related

How can I get and set cells values based on 2 criteria and 1st is date?

I'm struggling with my project. I can't get cell values, please if somebody help me with that.
In my project I have Roster tab and Holiday request tab, I want to find in roster tab cells that are in between dates from the Holiday request tab for that particular name and setValue("Holiday").
I tried with for loop, and didn't have any success, and map and get the indexOf column and find and no success to get it.
Here's the code I have
function Holidays() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
//Holiday request from
var master = ss.getSheetByName("Holiday Request");
//Roster tab
var target = ss.getSheetByName("Roster");
//
var values = target.getRange("A3:NI20").getValues();
var lc = target.getRange(3, 1, 1,target.getLastColumn()-1).getValues();
//
var appdis = master.getRange("G2:G250").getValues();
var name = master.getRange(2,3, master.getLastRow()-1, 1).getValues();
var sdate = master.getRange(2,4, master.getLastRow()-1, 1).getValues();
var edate = master.getRange(2,5, master.getLastRow()-1, 1).getValues();
sdate.map(d =>{
d[0]
var shd = sdate.find(n => n[0] == d[0])
name.map(n =>{
n[0]
var sname = values.find(r => r[0] == n[0])
for(i=0, j=0; i<values.lenght, j<values[i].lenght; i++, j++){
if(i == sname && j == shd)
var cells = values.getRange(i, j).getValues();
cells.setValues("Holiday");
}
})
})
}
Here is the file
https://docs.google.com/spreadsheets/d/1i3qMZgls3_WRPY5QSlQJo802D7xYDO80dih8E2-Vrd4/edit#gid=399093041
Any help will be really appreciated!
UPDATE!!!
I did research as I was advised. Now I am able to extract value for just one date from the list, as well I transformed the sname 2d array into Object. The difficult part is I still don't get it how to loop though the multiple dates that I have. With get.DisplayValue() it get one date, with get.DisplayValues() I can get all of them but can't get the indexOf all of them. Here's what I have
function Holidays() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
//Holiday request from
var hsheet = ss.getSheetByName("Holiday Request");
//Roster tab
var target = ss.getSheetByName("Roster");
// Roster values
//var dates = target.getDataRange().getDisplayValues();
var rosvalues = target.getRange(1, 1, target.getLastRow()-1,target.getLastColumn()-1).getValues();
var [, , dates, , ...rvalues] = target.getDataRange().getDisplayValues();
var sdate = hsheet.getRange(3, 4, hsheet.getLastRow()-1, 1).getDisplayValue();
//for(i=0; i<sdate.length; i++){
var col = dates.indexOf(sdate);
Logger.log(col)
//}
var sname = hsheet.getRange(2, 3, hsheet.getLastRow()-1, 1).getValues();
Logger.log(sdate)
Logger.log(sname)
var fcol = rvalues.reduce((o, r) => {
if(r[0]) o[r[0]] = r[col];
return o;
}, {});
Logger.log(fcol)
var nameObj = sname.reduce((a, [val1, val2]) => {
a[val1] = val2;
return a;
},{});
Logger.log(nameObj)
var textObj = { "08 - 17": "Holiday", "17 - 02": "Holiday", "11 - 20": "Holiday"};
var key1 = Object.keys(textObj);
var key2 = Object.keys(nameObj);
var cell = rosvalues.map((r, i) => r.map((c, j) => fcol[c] && key1.includes(fcol[c]) && key2.includes(fcol[c]) ? textObj[fcol[c]] : null));
cell.setValue("Holiday");
Logger.log(cell)
}
Please if you can tell me what I'm doing wrong. Thank you!
This function will calculate the total number of work days during the period of the holiday request and place that number in column 6 of the request sheet for each person on the list. I presumed that works days are days that do not contain the string "OFF"
function Holidays() {
const mA = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"];
const ss = SpreadsheetApp.getActive();
const req = ss.getSheetByName("Sheet0");//request sheet
const reqvs = req.getRange(2, 1, req.getLastRow() - 1, req.getLastColumn()).getValues();
const ros = ss.getSheetByName("Sheet1");//roster sheet
const rosdates = ros.getRange(3, 8, 1, ros.getLastColumn() - 7).getDisplayValues().flat();
const rosnames = ros.getRange(5, 1, ros.getLastRow() - 4).getDisplayValues().flat();
let vs;//I put vs up here so that I could see it in the debugger
reqvs.forEach(([, , n, s, e, d, ,], i) => {
let name = n;
let idx = rosnames.indexOf(name);
if (~idx) {
wds = 0;
let row = idx + 5;
let sd = new Date(s);//start date
let ed = new Date(e);//end date
const ds = dateStrings(sd, ed);
vs = rosdates.map((d, j) => { if (~ds.indexOf(d)) { return j + 8; } else { return ''; } }).filter(e => e);//returns column numbers and they are always consecutive
ros.getRange(row, vs[0], 1, vs.length).getValues().flat().forEach(v => { if (v != "OFF") { wds += 1; } });
req.getRange(i + 2, 6).setValue(wds)
}
});
}
function dateStrings(Day1,Day2) {
const mA = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sept","Oct","Nov","Dec"];
if(Day1 && Day2 && (Object.prototype.toString.call(Day1) === '[object Date]') && (Object.prototype.toString.call(Day2) === '[object Date]')) {
var day=86400000;
var t1=new Date(Day1).valueOf();
var t2=new Date(Day2).valueOf();
var d=Math.abs(t2-t1);
var days=Math.floor(d/day);
let dA = Array.from(new Array(days + 1).keys(),x => {
let dt = new Date(Day1.getFullYear(),Day1.getMonth(),Day1.getDate() + x);
return `${dt.getDate()} ${mA[dt.getMonth()]}`;
});
//Logger.log(dA);
return dA;
}
}
The Roster Sample Sheet:
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
21
23
25
27
29
31
33
35
37
39
2
Sun
Mon
Tue
Wed
Thu
Fri
Sat
Sun
Mon
Tue
Wed
Thu
Fri
Sat
Sun
Mon
Tue
Wed
Thu
Sat
Mon
Wed
Fri
Sun
Tue
Thu
Sat
Mon
Wed
3
1 Jan
2 Jan
3 Jan
4 Jan
5 Jan
6 Jan
7 Jan
8 Jan
9 Jan
10 Jan
11 Jan
12 Jan
13 Jan
14 Jan
15 Jan
16 Jan
17 Jan
18 Jan
19 Jan
21 Jan
23 Jan
25 Jan
27 Jan
29 Jan
31 Jan
2 Feb
4 Feb
6 Feb
8 Feb
4
Name
TL
Lang
EID
LI ID
Leaver
5
Name 1
Name 1
17 - 02
OFF
17 - 02
17 - 02
17 - 02
OFF
OFF
17 - 02
OFF
17 - 02
17 - 02
17 - 02
OFF
OFF
17 - 02
OFF
17 - 02
17 - 02
17 - 02
OFF
OFF
17 - 02
OFF
17 - 02
17 - 02
17 - 02
OFF
OFF
17 - 02
6
Name 2
Name 2
OFF
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
OFF
08 - 17
08 - 17
7
Name 3
Name 3
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
OFF
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
8
Name 4
Name 4
08 - 17
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
08 - 17
9
Name 5
Name 5
08 - 17
OFF
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
OFF
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
OFF
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
OFF
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
10
Name 6
Name 6
17 - 02
17 - 02
OFF
17 - 02
17 - 02
17 - 02
OFF
17 - 02
17 - 02
OFF
17 - 02
17 - 02
17 - 02
OFF
17 - 02
17 - 02
OFF
17 - 02
17 - 02
OFF
17 - 02
17 - 02
17 - 02
17 - 02
OFF
17 - 02
OFF
17 - 02
17 - 02
11
Name 7
Name 7
17 - 02
17 - 02
17 - 02
OFF
17 - 02
17 - 02
17 - 02
17 - 02
17 - 02
17 - 02
OFF
17 - 02
17 - 02
17 - 02
17 - 02
17 - 02
17 - 02
OFF
17 - 02
17 - 02
17 - 02
OFF
17 - 02
17 - 02
17 - 02
17 - 02
17 - 02
17 - 02
OFF
12
Name 9
Name 9
17 - 02
17 - 02
OFF
17 - 02
17 - 02
OFF
OFF
17 - 02
17 - 02
OFF
17 - 02
17 - 02
OFF
OFF
17 - 02
17 - 02
OFF
17 - 02
17 - 02
OFF
17 - 02
17 - 02
OFF
17 - 02
OFF
17 - 02
OFF
17 - 02
17 - 02
13
Name 10
Name 10
OFF
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
OFF
08 - 17
08 - 17
14
Name 11
Name 11
08 - 17
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
08 - 17
15
Name 12
Name 12
08 - 17
OFF
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
OFF
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
OFF
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
OFF
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
16
Name 13
Name 13
17 - 02
17 - 02
17 - 02
OFF
17 - 02
17 - 02
17 - 02
17 - 02
17 - 02
17 - 02
OFF
17 - 02
17 - 02
17 - 02
17 - 02
17 - 02
17 - 02
OFF
17 - 02
17 - 02
17 - 02
OFF
17 - 02
17 - 02
17 - 02
17 - 02
17 - 02
17 - 02
OFF
17
Name 14
Name 14
17 - 02
17 - 02
OFF
17 - 02
17 - 02
OFF
OFF
17 - 02
17 - 02
OFF
17 - 02
17 - 02
OFF
OFF
17 - 02
17 - 02
OFF
17 - 02
17 - 02
OFF
17 - 02
17 - 02
OFF
17 - 02
OFF
17 - 02
OFF
17 - 02
17 - 02
18
Name 15
Name 15
OFF
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
08 - 17
08 - 17
08 - 17
08 - 17
OFF
OFF
08 - 17
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
08 - 17
OFF
08 - 17
08 - 17
OFF
08 - 17
08 - 17
The Request Sample Sheet:
A
B
C
D
E
F
G
H
1
Request Date
Username
Name
Start Date
End Date
WorkDays
Approved
Reason
2
30 Mar
ag1
Name 1
1 Jan
6 Jan
4
3
31 Mar
ag2
Name 2
16 Jan
27 Jan
10
4
31 Mar
ag3
Name 3
10 Jan
20 Jan
8
creating markdown tables
google-apps-script reference
javascript reference
Learn More

MySQL String to DATE / TIME or TIMESTAMP

In my data set, the start and end time for a task is given as a string. The string contains:
'Day, Date Month YYYY HH:MM:SS GMT'
'Wed, 18 Oct 2017 10:11:03 GMT'
The previous questions on Stack Overflow do not have data in this format and I have been struggling how to convert it into DATE/TIME or TIMESTAMP. Any advice on this would be greatly appreciated!
This post was quite relevant but still does not meet my needs, as the format of the string is different in both cases:
Converting date/time string to unix timestamp in MySQL
Overall, I want to achieve a variable 'time_on_task' which takes the difference per person between their start_time and end_time. Thus, for the following data:
Person TaskID Start_time End_time
Alpha 1 'Wed, 18 Oct 2017 10:10:03 GMT' 'Wed. 18 Oct 2017 10:10:36 GMT'
Alpha 2 'Wed, 18 Oct 2017 10:11:16 GMT' 'Wed, 18 Oct 2017 10:11:28 GMT'
Beta 1 'Wed, 18 Oct 2017 10:12:03 GMT' 'Wed, 18 Oct 2017 10:12:49 GMT'
Alpha 3 'Wed, 18 Oct 2017 10:12:03 GMT' 'Wed, 18 Oct 2017 10:13:13 GMT'
Gamma 1 'Fri, 27 Oct 2017 22:57:12 GMT' 'Sat, 28 Oct 2017 02:00:54 GMT'
Beta 2 'Wed, 18 Oct 2017 10:13:40 GMT' 'Wed, 18 Oct 2017 10:14:03 GMT'
The required output would be something like this:
Person TaskID Time_on_task
Alpha 1 0:00:33 #['Wed, 18 Oct 2017 10:10:36 GMT' - 'Wed, 18 Oct 2017 10:10:03 GMT']
Alpha 2 0:00:12 #['Wed, 18 Oct 2017 10:11:28 GMT' - 'Wed, 18 Oct 2017 10:11:16 GMT']
Beta 1 0:00:46 #['Wed, 18 Oct 2017 10:12:49 GMT' - 'Wed, 18 Oct 2017 10:12:03 GMT']
Alpha 3 0:01:10 #['Sat, 18 Nov 2017 10:13:13 GMT' - 'Sat, 18 Nov 2017 10:12:03 GMT']
Gamma 1 3:03:42 #['Sat, 28 Oct 2017 02:00:54 GMT' - 'Fri, 27 Oct 2017 22:57:12 GMT']
Beta 2 0:00:23 #['Wed, 18 Oct 2017 10:14:03 GMT' - 'Wed, 18 Oct 2017 10:13:40 GMT']
You need STR_TO_DATE() to convert the string to a date. Consider:
select str_to_date(
'Wed, 18 Oct 2017 10:11:03 GMT',
'%a, %d %b %Y %T GMT'
)
Yields:
2017-10-18 10:11:03
Once you strings are converted to dates, you can use timestampdiff() to compute the difference between them, and turn the result back to a time using sec_to_time():
select
person,
taskID,
sec_to_time(
timestampdiff(
second,
str_to_date(Start_time, '%a, %d %b %Y %T GMT'),
str_to_date(End_time, '%a, %d %b %Y %T GMT')
)
) time_on_task
from mytable
Demo on DB Fiddlde:
| person | taskID | time_on_task |
| ------ | ------ | ------------ |
| Alpha | 1 | 00:00:33 |
| Alpha | 2 | 00:00:12 |
| Beta | 1 | 00:00:46 |
| Alpha | 3 | 00:01:10 |
| Gamma | 1 | 03:03:42 |
| Beta | 2 | 00:00:23 |

SQL sum and show row with non-existent sum values

i have 2 tables : dt_user and dt_invoice.
**dt_members :**
id firstname
3 Salim
5 Sara
8 Julie
**dt_invoice**
user_id amount_ht period month year
3 4950 04 2018 04 2018
3 7200 10 2018 10 2018
8 11000 10 2018 10 2018
8 5500 11 2018 11 2018
3 6750 11 2018 11 2018
3 8700 12 2018 12 2018
3 8800 01 2019 01 2019
8 7500 01 2019 01 2019
3 4950 02 2019 02 2019
3 7550 03 2019 03 2019
I want to create a query joining the two table, but i want to show each user_id for PERIOD that there is in table dt_invoice.
**Expected results :**
user_id amount_ht period month year
3 4950 04 2018 04 2018
5 0 04 2018 04 2018 //non-existent record in dt_invoice
8 0 04 2018 04 2018 //non-existent record in dt_invoice
3 7200 10 2018 10 2018
5 0 10 2018 10 2018 //non-existent record in dt_invoice
8 11000 10 2018 10 2018
8 5500 11 2018 11 2018
5 0 11 2018 11 2018 //etc ...
3 6750 11 2018 11 2018
3 8700 12 2018 12 2018
5 0 12 2018 12 2018
8 0 12 2018 12 2018
3 8800 01 2019 01 2019
5 0 01 2019 01 2019
8 7500 01 2019 01 2019
3 4950 02 2019 02 2019
5 0 02 2019 02 2018
8 0 02 2019 02 2018
3 7550 03 2019 03 2019
5 0 03 2019 03 2018
8 0 03 2019 03 2018
Thanks in advance for your help, i'm totally stuck ..
SQL datas available here : https://rextester.com/live/LBSEY76360
also in sqlfiddle : http://sqlfiddle.com/#!9/728af3/1
Use a cross join to generate the rows and left join to bring in the values:
select m.user_id, p.period, p.month, p.year,
coalesce(t.amount_ht, 0) as amount_ht
from dt_members m cross join
(select distinct period, month, year from dt_invoice) p left join
dt_invoice t
on t.user_id = m.id and t.period = p.period;
Maybe this would help.
SELECT user_id, amount_ht, period, month, year
FROM dt_invoice
LEFT JOIN dt_members ON user_id = id

multiple monthly averages for multiple years using sql

I am having a data set in the format which i'm attaching below. It contains data for, say, 25 years on a daily basis. I have to take out averages of each column (AA, BB, CC,DD) omitting null values, for a single / multiple months (not all months together) year wise: like avg of AA for the month of Jan and Jul from 90-95. I'm not able to frame a proper query.
NAME DD MM YYYY TIME AA BB CC DD
DLH 01 01 1986 0000 0
DLH 01 01 1986 0100 0
DLH 01 01 1986 0200 0
DLH 01 01 1986 0230 0 6 5 94
DLH 01 01 1986 0300 0
DLH 01 01 1986 0400 0
DLH 01 01 1986 0500 0
DLH 01 01 1986 0530 0 6 5 94
DLH 01 01 1986 0600 0 6
DLH 01 01 1986 0700 0 6
DLH 01 01 1986 0800 0 8
DLH 01 01 1986 0830 0 9 8 95
DLH 01 01 1986 0900 0 9
DLH 01 01 1986 1000 2 14
DLH 01 01 1986 1100 2 17
DLH 01 01 1986 1115 5
DLH 01 01 1986 1130 7 17 9 60
DLH 01 01 1986 1140 7
DLH 01 01 1986 1145 7
DLH 01 01 1986 1150 7
DLH 01 01 1986 1200 8 18
DLH 01 01 1986 1300 6 18
DLH 01 01 1986 1400 10 18
DLH 01 01 1986 1430 7 18 8 50
Assuming I understand your question properly, I would do the following for the example given:
SELECT AVG(x.AA)
FROM
(SELECT AA
FROM Table1
WHERE MM IN (1,7) AND YYYY BETWEEN 1990 AND 1995) x

How to merge[union] one column[field] data in MySQL!

E.g: DISTINCT file_sn and got the merge[union,unique] all_files result:
user_id file_sn all_files[char]
1 1 01 02 05
2 1 02 05
3 1 05 06 07 08
4 1 10 11 12 15
So,I want to merge[union] the column: all_files so I could get the unique all_files data like:
01 02 05 06 07 08 10 11 12 15
Thank you very much~~
[UPDATE]
My query to get the all all_files query:
SELECT file_sn, GROUP_CONCAT(DISTINCT all_files SEPARATOR ' ')
FROM `myTable`
GROUP BY file_sn
It will return:
01 02 05 02 05 05 06 07 08 05 06 07 08