Время набора программно с помощью C#

Ваша проблема

Проблема, с которой вы сталкиваетесь, связана с тем, что вы удаляете столбцы внутри своего диапазона цикла. Когда вы удаляете столбец, диапазон, который вы циклически изменяете, приводит к пропуску столбцов (в соответствии с вашими результатами). Чтобы бороться с этим, вы можете использовать метод Union, который позволяет удалять столбцы вне цикла, чтобы вы не столкнулись с сообщенной проблемой. В нижнем решении показано, как исправить сообщенную проблему, если вы решили удалить столбцы внутри цикла.


Выберите вариант

Select Case. Прокрутите диапазон и, если ячейка отсутствует в списке в первом случае, она будет помечена для удаления во втором случае (Case Else).

После того, как вы зациклили свои заголовки, удалите все столбцы сразу, что означает, что во время зацикливания смещения диапазона не будет.

Sub DeleteColumns()

Dim iCell As Range, DeleteMe As Range

For Each iCell In Range("A1:W1")
    Select Case iCell
        Case "Cartons", "ShipVia", "Name", "Address", "City", "State", "Zip"
            'Do Nothing
        Case Else
            If Not DeleteMe Is Nothing Then
                Set DeleteMe = Union(DeleteMe, iCell)
            Else
                Set DeleteMe = iCell
            End If
    End Select
Next iCell

If Not DeleteMe Is Nothing Then DeleteMe.EntireColumn.Delete

End Sub

Array

Вы также можете перебирать массив. Обратите внимание, что цикл столбца движется в обратном направлении, чтобы остановить смещение соответствующего диапазона внутри цикла (ваша первоначальная проблема). Для этого вам нужно сбросить цикл For Each и переключиться на For j = # - #, чтобы вы могли использовать свойство Step -1

Sub Array_Method()

Dim Arr: Arr = Array("Cartons", "ShipVia", "Name", "Address", "City", "State", "Zip")
Dim i As Long, j As Long

For j = 23 To 1 Step -1
    For i = UBound(Arr) To LBound(Arr)
        If Arr(i) = Cells(1, j) Then
            Cells(1, j).EntireColumn.Delete
        End If
    Next i
Next j

End Sub
7
задан Lance Roberts 15 October 2008 в 14:32
поделиться

4 ответа

Я использовал бы Windows встроенные интернет-способности времени. Можно настроить сервер времени на сервере, иметь его, получают время от 2-го уровневого сервера времени и имеют все клиентские машины, получают время от него.

Я снизился на application-setting-system-time дорогу прежде.

5
ответ дан 6 December 2019 в 11:54
поделиться

Это - вызов API Win32 установки системного времени:

[StructLayout(LayoutKind.Sequential)] 
public struct SYSTEMTIME { 
 public short wYear; 
 public short wMonth; 
 public short wDayOfWeek; 
 public short wDay; 
 public short wHour; 
 public short wMinute; 
 public short wSecond; 
 public short wMilliseconds; 
 } 
 [DllImport("kernel32.dll", SetLastError=true)] 
public static extern bool SetSystemTime(ref SYSTEMTIME theDateTime ); 

Я не абсолютно уверен, как Вы разработали бы безопасность, таким образом, что Вы могли выполнить ту функцию на клиенте, все же.

Можно получить намного больше детали об установке системного времени в PInvoke.

8
ответ дан 6 December 2019 в 11:54
поделиться

Вы могли также, вероятно, сделать это в пакетном файле с помощью некоторой комбинации

TIME

установить время, и

net time \\server_name

получать время с сервера.

0
ответ дан 6 December 2019 в 11:54
поделиться

Способом запросить сетевую машину, поскольку это - системное время, является NetRemoteTOD.

Вот код, чтобы сделать это в Delphi (пример использования отправляется ниже).

Так как это полагается на Windows API calls, это не должно слишком отличаться в C#.

unit TimeHandler;

interface

type
  TTimeHandler = class
  private
    FServerName : widestring;
  public
    constructor Create(servername : widestring);
    function RemoteSystemTime : TDateTime;
    procedure SetLocalSystemTime(settotime : TDateTime);
  end;

implementation

uses
  Windows, SysUtils, Messages;

function NetRemoteTOD(ServerName :PWideChar; var buffer :pointer) : integer; stdcall; external 'netapi32.dll';
function NetApiBufferFree(buffer : Pointer) : integer; stdcall; external 'netapi32.dll';

type
  //See MSDN documentation on the TIME_OF_DAY_INFO structure.
  PTime_Of_Day_Info = ^TTime_Of_Day_Info;
  TTime_Of_Day_Info = record
    ElapsedDate : integer;
    Milliseconds : integer;
    Hours : integer;
    Minutes : integer;
    Seconds : integer;
    HundredthsOfSeconds : integer;
    TimeZone : LongInt;
    TimeInterval : integer;
    Day : integer;
    Month : integer;
    Year : integer;
    DayOfWeek : integer;
  end;

constructor TTimeHandler.Create(servername: widestring);
begin
  inherited Create;
  FServerName := servername;
end;

function TTimeHandler.RemoteSystemTime: TDateTime;
var
  Buffer : pointer;
  Rek : PTime_Of_Day_Info;
  DateOnly, TimeOnly : TDateTime;
  timezone : integer;
begin
  //if the call is successful...
  if 0 = NetRemoteTOD(PWideChar(FServerName),Buffer) then begin
    //store the time of day info in our special buffer structure
    Rek := PTime_Of_Day_Info(Buffer);

    //windows time is in GMT, so we adjust for our current time zone
    if Rek.TimeZone <> -1 then
      timezone := Rek.TimeZone div 60
    else
      timezone := 0;

    //decode the date from integers into TDateTimes
    //assume zero milliseconds
    try
      DateOnly := EncodeDate(Rek.Year,Rek.Month,Rek.Day);
      TimeOnly := EncodeTime(Rek.Hours,Rek.Minutes,Rek.Seconds,0);
    except on e : exception do
      raise Exception.Create(
                             'Date retrieved from server, but it was invalid!' +
                             #13#10 +
                             e.Message
                            );
    end;

    //translate the time into a TDateTime
    //apply any time zone adjustment and return the result
    Result := DateOnly + TimeOnly - (timezone / 24);
  end  //if call was successful
  else begin
    raise Exception.Create('Time retrieval failed from "'+FServerName+'"');
  end;

  //free the data structure we created
  NetApiBufferFree(Buffer);
end;

procedure TTimeHandler.SetLocalSystemTime(settotime: TDateTime);
var
  SystemTime : TSystemTime;
begin
  DateTimeToSystemTime(settotime,SystemTime);
  SetLocalTime(SystemTime);
  //tell windows that the time changed
  PostMessage(HWND_BROADCAST,WM_TIMECHANGE,0,0);
end;

И вот пример использования:

procedure TfrmMain.SynchLocalTimeWithServer;
var
  tod : TTimeHandler;
begin
  tod := TTimeHandler.Create(cboServerName.Text);
  try
    tod.SetLocalSystemTime(tod.RemoteSystemTime);
  finally
    FreeAndNil(tod);
  end;  //try-finally
end;
3
ответ дан 6 December 2019 в 11:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: